javascript - scrapy-splash 用于渲染 javascript

标签 javascript python python-2.7 scrapy

这是我的 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/

相关文章:

javascript - 有没有办法知道用户是否使用类似于使用 col-sm 的 flexbox 的小型设备?

javascript - 防止nodejs应用程序退出

python - 来自发布原始数据的django ImageField

inheritance - 打印为我提供了类列表上的内存地址,而不是特定的 STR

javascript - VueJS : Error when looping through data array with component

JavaScript 对象和通过对话框持久化

python - 计算 pytorch 中分类的交叉熵损失

python - 说明 Hadoop 与 RabbitMQ+Celery 的用例

python - 获取字典中每个键对 (n0, a), (n0, b) 的最大值的键对 (n0, _), (n1, _)

javascript - 使用 jquery Ajax 删除 django 中的模型对象