您的位置:首页 > 其它

scrapy 抓取ajax请求的网页-以ifanr为例

2016-03-16 13:38 423 查看
在爬取ifanr网站时遇到了无法直接获得下一页链接的地址,下一页的数据是通过点击加载更多之后触发ajax事件来请求数据的。



那么我们按F12来看下网页的结构,可以发现此处并不能够得到我们想要的网址。



那么问题来了,我们如何来处理有ajax请求的网页呢?百度一下可以发现有两种方法,一种是通过虚拟浏览器模仿触发ajax请求的行为;一种是找出ajax请求之后下一页的地址,直接访问该地址。这里我们采用第二种方法。

选择network-XHR,新出现的请求便是我们需要分析的。



点开可以Request URL得到链接地址:
http://www.ifanr.com/api/v3.0/?action=ifr_latest&callback=jQuery110107388741704635322_1458106436991&offset_featured=1&posts_per_page=28&excerpt_length=200& thumb_size=120xauto&paged=2&page=2&cancel_cache=false&add_dasheng_fields=true&appkey=lI5287M8UyxBI98U2YKq×tamp=1458106307& sign=e2de6f1a979789e59058c5cf6528e601&_=1458106436994



分析一下该链接,可以删去一些无用的参数。其中paged=2表示本页是第二页,posts_per_page=28表示每页有28个文章。这是最主要的两个参数。最后我们删去一些参数后打开其他的浏览器访问,(由于我们在当前浏览器打开的时候带有一定的请求参数,如果在其他的浏览器仍能访问该链接说明这个api借口本身是public)。如图我们就得到了熟悉的json字符串了。



在这里给大家推荐个小工具,chrome浏览器的工具JSON-handle,查看json数据清晰明了。



这里面的link便是我们要抓取的文章的网址。下面上代码喽~~~~~~~~~~

#-*-coding:utf-8-*-
from scrapy.spider import Spider
from scrapy.selector import Selector
from allpapers.items import PaperItem
from scrapy import Request
from scrapy import log
from datetime import datetime
import re
import requests

class IfanrSpider(Spider):

name = "Ifanr"
download_delay = 1
allowed_domains = ['ifanr.com']
start_urls = ['http://www.ifanr.com']

def parse(self,response):
response_selector = Selector(response)
for detail_link in response_selector.xpath('//article/div/a/@href').extract():
if detail_link:
try:
yield Request(url=detail_link, callback=self.parse_items)
except:
yield Request(url=detail_link, callback=self.parse_items)
log.msg("Page " + detail_link + " parse ERROR, try again !", level=log.WARNING)
first_url = 'http://www.ifanr.com/api/v3.0/?action=ifr_latest&posts_per_page=28&paged={page_index}'
for index in range(2,1100):
next_url=first_url.replace('{page_index}',str(index))
r = requests.get(next_url)
objs=r.json()['data']
for j in range(len(objs)):
obj = objs[j].get('link')
yield Request(url=obj, callback=self.parse_items)

def parse_items(self, response):
item = PaperItem()
sel = Selector(response)

item['paper_url'] = str(response.url)
item['paper_title']=sel.xpath('//div[@class="entry-header"]/h1/text()').extract()
if not item['paper_title']:
item['paper_title']=sel.xpath('//div[@class="post-item-content"]/h1/text()').extract()
item['all_title']= sel.xpath('//title/text()').extract()
item['paper_photo']=sel.xpath('//*[@itemprop="articleBody"]//img/@src|//*[@id="content"]/div[1]/div[2]/div[1]/div[2]/img/@src').extract()
item['paper_all']=sel.xpath('//*[@itemprop="articleBody"]//text()').extract()
item['paper_time']=sel.xpath('//div[@class="tag-label"]/span/@datetime').extract()
if not item['paper_time']:
item['paper_time']=sel.xpath('//div[@class="tag-label"]/text()[3]').re(u'(20\d+.*)')
print item['paper_time']
item['paper_author']=sel.xpath('//div[@class="tag-label"]/meta[1]/@content').extract()
if not item['paper_author']:
item['paper_author']=sel.xpath('//div[@class="tag-label"]/a[@rel="author"]/text()').extract()
item['paper_collect']=[]#sel.xpath('//span[@class="ifanr-share-tip"]/span/text()').extract()
item['paper_tag']=sel.xpath('//div[@class="entry-meta-tags"]/a/text()').extract()

yield item


本人菜鸟一枚,请见谅。欢迎批评指正~~~~~~禁止用于不正当用途,在此仅作为学习交流~~~~~~~~~~~~~~~~~~~~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: