这是我的previous quesion
的后续跟进我安装了splash和scrapy-splash。
并且跟随instructions进行了scrapy-splash。
我按如下方式编辑了我的代码:
import scrapy
from scrapy_splash import SplashRequest
class CityDataSpider(scrapy.Spider):
name = "citydata"
def start_requests(self):
urls = [
'http://www.city-data.com/advanced/search.php#body?fips=0&csize=a&sc=2&sd=0&states=ALL&near=&nam_crit1=6914&b6914=MIN&e6914=MAX&i6914=1&nam_crit2=6819&b6819=15500&e6819=MAX&i6819=1&ps=20&p=0',
'http://www.city-data.com/advanced/search.php#body?fips=0&csize=a&sc=2&sd=0&states=ALL&near=&nam_crit1=6914&b6914=MIN&e6914=MAX&i6914=1&nam_crit2=6819&b6819=15500&e6819=MAX&i6819=1&ps=20&p=1',
]
for url in urls:
yield SplashRequest(url=url, callback=self.parse)
def parse(self, response):
page = response.url.split("/")[-2]
filename = 'citydata-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log('Saved file %s' % filename)
但我仍然得到相同的输出。只生成一个html文件,结果仅适用于http://www.city-data.com/advanced/search.php
代码中是否有任何错误或请提出任何其他建议。
答案 0 :(得分:1)
首先,我想从你的上一个问题“@paul trmbrth”写道中找出一些可能的混淆点:
URL片段(即#body之后和之后的所有内容)不会发送到服务器,只会获取http://www.city-data.com/advanced/search.php
因此,对于Scrapy,对[...]和[...]的请求是相同的资源,所以它只获取一次。它们的URL片段不同。
URI标准规定数字符号(#)用于表示片段的开头,这是URL的最后一部分。在大多数/所有浏览器中,除“#”之外的任何内容都不会传输。 然而 ,AJAX网站使用Javascript的window.location.hash
抓取URL片段并使用它来执行其他AJAX调用是相当常见的。我提出这个问题是因为city-data.com就是这样做的,这可能会让你感到困惑,因为它实际上会为浏览器中的每个网址带回两个不同的网站。
默认情况下,Scrapy会删除网址片段,因此它会将两个网址报告为“http://www.city-data.com/advanced/search.php”,并过滤第二个网址。
完成所有这些操作后,从page = response.url.split("/")[-2]
和filename = 'citydata-%s.html' % page
的组合中删除网址中的“#body”后仍会出现问题。您的网址都没有重定向,因此提供的网址将填充response.url
字符串。
隔离它,我们得到以下结果:
>>> urls = [
>>> 'http://www.city-data.com/advanced/search.php?fips=0&csize=a&sc=2&sd=0&states=ALL&near=&nam_crit1=6914&b6914=MIN&e6914=MAX&i6914=1&nam_crit2=6819&b6819=15500&e6819=MAX&i6819=1&ps=20&p=0',
>>> 'http://www.city-data.com/advanced/search.php?fips=0&csize=a&sc=2&sd=0&states=ALL&near=&nam_crit1=6914&b6914=MIN&e6914=MAX&i6914=1&nam_crit2=6819&b6819=15500&e6819=MAX&i6819=1&ps=20&p=1',
>>> ]
>>> for url in urls:
... print(url.split("/")[-2])
advanced
advanced
因此,对于这两个网址,您正在提取相同的信息,这意味着当您使用filename = 'citydata-%s.html' % page
时,您将获得相同的文件名,我认为这将是'citydata-advanced.html ”。第二次调用时,你将覆盖第一个文件。
根据您对数据的处理方式,您可以将其更改为附加到文件,或将文件名变量修改为唯一的内容,例如:
from urlparse import urlparse, parse_qs
import scrapy
from scrapy_splash import SplashRequest
class CityDataSpider(scrapy.Spider):
[...]
def parse(self, response):
page = parse_qs(urlparse(response.url).query).get('p')
filename = 'citydata-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log('Saved file %s' % filename)