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

来源:互联网 发布:屏幕触摸检测软件 编辑:程序博客网 时间:2024/05/16 23:40

在爬取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&timestamp=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 Spiderfrom scrapy.selector import Selectorfrom allpapers.items import PaperItemfrom scrapy import Requestfrom scrapy import logfrom datetime import datetimeimport reimport requestsclass 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

本人菜鸟一枚,请见谅。欢迎批评指正~~~~~~禁止用于不正当用途,在此仅作为学习交流~~~~~~~~~~~~~~~~~~~~~~~


2 0