如何使scrapy遵循javascript生成的url?

时间:2015-06-07 08:16:21

标签: python selenium web-crawler scrapy scrapy-spider

我想在此网站抓取新闻:new.scut.edu.cn 但是在它的子网站this中,右下角的下一页(中文下一页)网址是由javascript生成的。下一页的html源代码是<a name="_l_p_n" href="javascript:if(true){a_next('/s/22/t/4/p/69/c/7/i//list.htm');}" title="进入下一页">下一页</a>,引用脚本是

var _currentPageIndex =346;
var _listArticleCount =-1;       
var _listPaginationCount =-1; 
function a_next(url) {           
if(_currentPageIndex > 1) {               
location.href =url.replace('i/','i/'+(_currentPageIndex-1));
}                
}

我想抓取所有网页,因此蜘蛛需要按照下一页进行操作。这是我的scrapy蜘蛛代码:

# -*- coding: utf-8 -*-

import scrapy
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
from scrapy.selector import Selector
from scutnews.items import ScutnewsItem
from scrapy.http import Request, FormRequest
import re

class NewsSpider(CrawlSpider):
    name = "scutnews"
    allowed_domain = ["news.scut.edu.cn"]
    start_urls = ["news.scut.edu.cn"]

    rules = (
            Rule(LinkExtractor(allow=(r"http://news.scut.edu.cn/s/22/t/.+/list.*"))),
            Rule(LinkExtractor(allow=(r"http://news.scut.edu.cn/s/22/t/.+/info.*")), callback = "parse_item")
            )

    def start_requests(self):
        yield FormRequest("http://news.scut.edu.cn", headers={'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0'})

    def parse_item(self, response):
        sel = Selector(response)
        item = ScutnewsItem()
       # item['title'] = sel.xpath('//div[@class="display_news_con"]/h1/text()').extract()
       # item['time'] = sel.xpath('//span[@class="posttime"]/text()').extract()
        item['content'] = sel.xpath('//div[@class="infobox"]/div[1]/p/text()|//div[@class="infobox"]/div[1]/p/span/text()|//div[@class="infobox"]/div[1]/p/span/span/text()|//div[@class="infobox"]/div[1]/p/span/span/span/text()|//div[@class="infobox"]/div[1]/text()').extract()
       # item['url'] = response.url
        return item

我发现当前页面网址只是与下一页网址不同的一个数字。 我知道有一些解决方案,模拟javascript逻辑或使用像selenium和phantomjs这样的库。如何在模拟js逻辑的方式中修复scrapy spider代码以遵循下一页?需要改变scrapy蜘蛛规则吗?硒或幻影的方式呢? 提前致谢

1 个答案:

答案 0 :(得分:1)

我想提出一种不渲染javascript的方法,但是从页面中提取javascript信息。

您可以在select * from table where col1=searchkey or col2=searchkey or col3=searchkey;

之后为parse_list添加Rule个回调
list-pages

并在回调函数中实现一个正则表达式来解析rules = ( Rule(LinkExtractor(allow=(r"http://news.scut.edu.cn/s/22/t/.+/list.*")), callback = "parse_list"), Rule(LinkExtractor(allow=(r"http://news.scut.edu.cn/s/22/t/.+/info.*")), callback = "parse_item") ) 并获取(列表中的)页面总数:

javascript

如果有def parse_list(self, response): sel = Selector(response) xpath_pageCounter = './/script[@language="javascript" and contains(.,"currentPageIndex")]' pageCounter = sel.xpath(xpath_pageCounter).re(r'currentPageIndex =(\d+);') if pageCounter: page_Number = int(pageCounter[0]) - 1 page_url = response.url.replace('/list.htm', '/i/' + str(page_Number) + '/list.htm') print '#####', response.url, page_Number, page_url yield scrapy.FormRequest(page_url, callback=self.parse_item) ,您可以在循环中创建所有页码链接(直到第一页),并将这些page_Number传递给抓取工具。

上面的代码不起作用,但可以作为起点。