这是我上一个问题的后续问题
我安装了splash和scrapy-splash。
并且也遵循了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
代码中是否有任何错误或其他建议。
首先,我想澄清你上一个问题中可能存在的混淆点,"@paul trmbrth"写道:
URL片段(即包括#body和之后的所有内容)不发送到服务器,只获取http://www.city-data.com/advanced/search.php
所以对于Scrapy,请求[…]和……]是相同的资源,所以只需要fetch一次。它们的区别只在于URL片段。
URI标准规定使用数字符号(#)来表示片段的开始,这是URL的最后一部分。在大多数/所有浏览器中,除了"#"之外什么都不会传输。然而, AJAX站点利用Javascript的window.location.hash
抓取URL片段并使用它来执行额外的AJAX调用是相当常见的。我提到这个是因为citydata.com就是这样做的,这可能会让你感到困惑,因为它实际上会在浏览器中为每个url返回两个不同的站点。
Scrapy在默认情况下会删除URL片段,所以它会将两个URL都报告为"http://www.city-data.com/advanced/search.php",并过滤第二个。
有了所有这些,仍然会有问题,当你从url中删除"#body"由page = response.url.split("/")[-2]
和filename = 'citydata-%s.html' % page
的组合造成的。这两个URL都不是重定向的,所以所提供的URL将填充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
所以,对于两个URL,你提取相同的信息,这意味着当你使用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)