我想抓取这个网站的新闻: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));
}
}我想爬行所有的页面,所以爬虫需要跟随下一页。下面是我的爬虫代码:
# -*- 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逻辑的方式修复抓取的爬行器代码来跟随下一页?需要改变抓取蜘蛛的规则吗?以硒或幻影的方式呢?提前感谢
发布于 2015-06-09 21:05:31
我想提出一种不渲染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,您可以在循环中创建所有页码链接(一直到第一页),并将这些requests传递给爬虫程序。
上面显示的代码不起作用,但可以作为起点。
https://stackoverflow.com/questions/30691449
复制相似问题