这是我的 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
代码有什么问题或者有其他建议吗?
最佳答案
首先,我想澄清“@paul trmbrth”所写的上一个问题中可能存在的一些混淆点:
The URL fragment (i.e. everything including and after #body) is not sent to the server and only http://www.city-data.com/advanced/search.php is fetched
So for Scrapy, the requests to [...] and [...] are the same resource, so it's only fetch once. They differ only in their URL fragments.
URI 标准规定使用井号 (#) 来指示片段的开始,即 URL 的最后部分。在大多数/所有浏览器中,除了“#”之外,不会传输任何内容。 但是,AJAX 站点利用 Javascript 的 window.location.hash
抓取 URL 片段并使用它来执行其他 AJAX 调用是相当常见的。我提出这一点是因为 city-data.com 正是这样做的,这可能会让您感到困惑,因为它实际上会为浏览器中的每个 URL 返回两个不同的站点。
Scrapy 默认情况下会删除 URL 片段,因此它会将两个 URL 报告为“http://www.city-data.com/advanced/search.php ”,并过滤第二个 URL。
<小时/>完成所有这些后,从 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)
关于javascript - scrapy-splash 用于渲染 javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40262194/