是的,可以自动检索这些 url,但您必须弄清楚 ajax 加载内容的 url 是什么。这是一个简单的教程。
1. 做好研究
在 Chrome 控制台中,如果您打开网络选项卡,并按 xml 请求进行过滤,您将获得“启动器”字段。右侧有 javascript 文件,其中包含负责生成请求的代码。 Chrome 控制台显示调用请求的行。
在你的情况下,最重要的代码是
在文件 jquery-projects.js 的第 415 行中,该行内容如下:
$.ajax({
async: true,
type: 'GET',
url: URL,
正如你所看到的,这里有一个 URL 变量。您需要找到它的编码位置,只需上面几行:
var URL = '/projects/index.cfm?fuseaction=app.csa'; // production
switch(type) {
...
case 'doc':
URL += '&action=read&xslt-template=projects/xsl/projectdet_' + I18n.locale + '.xslt&rcn=' + me.ref;
break;
}
因此,url 是通过添加基本 url、以 action 开头的字符串以及两个变量 I18n.locale 和 me.ref 来生成的。请记住,此 url 是相对的,因此您还需要获取 url 根。
i18n.locale 原来只是一个字符串“_en”,me.ref 从哪里来?
再次在“源”选项卡中的控制台中按 ctrl + find,您会找到这行 jQuery:
// record reference
me.ref = $("#PrjSrch>input[name='REF']").val();
结果发现每个 url 都有一个隐藏表单,每次生成请求时都会从 me.ref 字段获取值。
现在您只需要将这些知识应用到您的 scrapy 项目中即可。
2. 运用你在 scrapy 蜘蛛中的知识。
此时您知道自己必须做什么。您需要从所有项目的起始 url 开始,获取所有链接,对这些链接发出请求,然后从每个请求后收到的内容中提取 ajax url,并为我们从那里获得的 url 生成请求。
from scrapy.selector import Selector
from scrapy.spider import Spider
from scrapy.http import Request
from eu.items import EuItem
from urlparse import urljoin
class CordisSpider(Spider):
name = 'cordis'
start_urls = ['http://cordis.europa.eu/fp7/security/projects_en.html']
base_url = "http://cordis.europa.eu/projects/"
# template string for ajax request based on what we know from investigating webpage
base_ajax_url = "http://cordis.europa.eu/projects/index.cfm?fuseaction=app.csa&action=read&xslt-template=projects/xsl/projectdet_en.xslt&rcn=%s"
def parse(self, response):
"""
Extract project links from start_url, for each generate GET request,
and then assign a function self.get_ajax_content to handle response.
"""
hxs = Selector(response)
links = hxs.xpath("//ul/li/span/a/@href").extract()
for link in links:
link = urljoin(self.base_url,link)
yield Request(url=link,callback=self.get_ajax_content)
def get_ajax_content(self,response):
"""
Extract AJAX link and make a GET request
for the desired content, assign callback
to handle response from this request.
"""
hxs = Selector(response)
# xpath analogy of jquery line we've seen
ajax_ref = hxs.xpath('//form[@id="PrjSrch"]//input[@name="REF"]/@value').extract()
ajax_ref = "".join(ajax_ref)
ajax_url = self.base_ajax_url % (ajax_ref,)
yield Request(url=ajax_url,callback=self.parse_items)
def parse_items(self,response):
"""
Response here should contain content
normally loaded asynchronously with AJAX.
"""
xhs = Selector(response)
# you can do your processing here
title = xhs.xpath("//div[@class='projttl']//text()").extract()
i = EuItem()
i["title"] = title
return i