【问题标题】:scrapy-splash usage for rendering javascript用于渲染 javascript 的 scrapy-splash 用法
【发布时间】:2017-03-08 19:33:17
【问题描述】:

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

代码中是否有任何错误或任何其他建议。

【问题讨论】:

  • 使用按钮{} 正确格式化代码。你收到错误信息吗?显示有问题。
  • 对我来说,你读了两页,但你把两页都写在同一个文件中——看看你是如何生成文件名的。
  • 可能会删除两个网址中的#body。它只是页面代码中的内部位置,因此某些系统期望在 url 末尾出现 #,并且它们会删除 # 之后的所有内容
  • @furas 即使我从网址中删除了 # 正文,我仍然无法在输出中找到任何更改。还有其他建议吗?

标签: javascript python python-2.7 scrapy scrapy-spider


【解决方案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 正是这样做的,这可能会让你感到困惑,因为它实际上为浏览器中的每个 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-30
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多