Skip to main content
 首页 » 编程设计

python之如何让 scrapy 跟随由 javascript 生成的 url

2025年05月04日32langtianya

我要爬取本站新闻:new.scut.edu.cn 但在它的子网站上,如 this ,右下角的下一页(中文下一页)url是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 

我发现当前页面 url 与下一页 url 仅相差一个数字。 我知道有一些解决方案,模拟 javascript 逻辑或使用像 selenium 和 phantomjs 这样的库。如何通过模拟js逻辑的方式修复scrapy spider代码跟随下一页?需要更改 scrapy 蜘蛛规则? selenium 或 phantomjs 的方式怎么样? 提前致谢

请您参考如下方法:

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

您可以在 list-pages 之后向您的 Rule 添加一个 parse_list 回调

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,您可以在循环中创建所有页码链接(一直到第一页)并将这些请求传递给抓取工具。

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