【问题标题】:How can Scrapy deal with JavascriptScrapy如何处理Javascript
【发布时间】:2015-11-15 11:54:00
【问题描述】:

蜘蛛供参考:

import scrapy
from scrapy.spiders import Spider
from scrapy.selector import Selector
from script.items import ScriptItem



    class RunSpider(scrapy.Spider):
        name = "run"
        allowed_domains = ["stopitrightnow.com"]
        start_urls = (
            'http://www.stopitrightnow.com/',
        )



        def parse(self, response):


            for widget in response.xpath('//div[@class="shopthepost-widget"]'):
                #print widget.extract()
                item = ScriptItem()
                item['url'] = widget.xpath('.//a/@href').extract()
                url = item['url']
                #print url
                yield item

当我运行它时,终端中的输出如下:

2015-08-21 14:23:51 [scrapy] DEBUG: Scraped from <200 http://www.stopitrightnow.com/>
{'url': []}
<div class="shopthepost-widget" data-widget-id="708473">
<script type="text/javascript">!function(d,s,id){var e, p = /^http:/.test(d.location) ? 'http' : 'https';if(!d.getElementById(id)) {e = d.createElement(s);e.id = id;e.src = p + '://' + 'widgets.rewardstyle.com' + '/js/shopthepost.js';d.body.appendChild(e);}if(typeof window.__stp === 'object') if(d.readyState === 'complete') {window.__stp.init();}}(document, 'script', 'shopthepost-script');</script><br>

这是html:

<div class="shopthepost-widget" data-widget-id="708473" data-widget-uid="1"><div id="stp-55d44feabd0eb" class="stp-outer stp-no-controls">
    <a class="stp-control stp-left stp-hidden">&lt;</a>
    <div class="stp-inner" style="width: auto">
        <div class="stp-slide" style="left: -0%">
                        <a href="http://rstyle.me/iA-n/zzhv34c_" target="_blank" rel="nofollow" class="stp-product " data-index="0" style="margin: 0 0px 0 0px">
                <span class="stp-help"></span>
                <img src="//images.rewardstyle.com/img?v=2.13&amp;p=n_24878713">
                            </a>
                        <a href="http://rstyle.me/iA-n/zzhvw4c_" target="_blank" rel="nofollow" class="stp-product " data-index="1" style="margin: 0 0px 0 0px">
                <span class="stp-help"></span>
                <img src="//images.rewardstyle.com/img?v=2.13&amp;p=n_24878708">

对我来说,尝试激活 Javascript 时似乎遇到了障碍。我知道javascript不能在scrapy中运行,但必须有一种方法可以访问这些链接。我看过硒,但无法掌握它。

欢迎任何和所有帮助。

【问题讨论】:

    标签: javascript selenium web-scraping scrapy scrapy-spider


    【解决方案1】:

    我已经用ScrapyJS 解决了这个问题。

    按照官方文档和this answer中的设置说明进行操作。

    这是我用过的测试蜘蛛:

    # -*- coding: utf-8 -*-
    import scrapy
    
    
    class TestSpider(scrapy.Spider):
        name = "run"
        allowed_domains = ["stopitrightnow.com"]
        start_urls = (
            'http://www.stopitrightnow.com/',
        )
    
        def start_requests(self):
            for url in self.start_urls:
                yield scrapy.Request(url, meta={
                    'splash': {
                        'endpoint': 'render.html',
                        'args': {'wait': 0.5}
                    }
                })
    
        def parse(self, response):
            for widget in response.xpath('//div[@class="shopthepost-widget"]'):
                print widget.xpath('.//a/@href').extract()
    

    这是我在控制台上得到的:

    [u'http://rstyle.me/iA-n/7bk8r4c_', u'http://rstyle.me/iA-n/7bk754c_', u'http://rstyle.me/iA-n/6th5d4c_', u'http://rstyle.me/iA-n/7bm3s4c_', u'http://rstyle.me/iA-n/2xeat4c_', u'http://rstyle.me/iA-n/7bi7f4c_', u'http://rstyle.me/iA-n/66abw4c_', u'http://rstyle.me/iA-n/7bm4j4c_']
    [u'http://rstyle.me/iA-n/zzhv34c_', u'http://rstyle.me/iA-n/zzhvw4c_', u'http://rstyle.me/iA-n/zwuvk4c_', u'http://rstyle.me/iA-n/zzhvr4c_', u'http://rstyle.me/iA-n/zzh9g4c_', u'http://rstyle.me/iA-n/zzhz54c_', u'http://rstyle.me/iA-n/zwuuy4c_', u'http://rstyle.me/iA-n/zzhx94c_']
    

    【讨论】:

    • 这太棒了,但是它只是在控制台中挂了很长时间:2015-08-21 16:36:14 [scrapy] 信息:已爬取 0 页(以 0 页/分钟),已抓取0 项(0 项/分钟)2015-08-21 16:37:00 [scrapy] 调试:放弃重试 192.168.59.103:8050/render.html>(失败 3 次):TCP 连接超时:60:操作超时。 2015-08-21 16:37:00 [scrapy] 错误:下载错误 192.168.59.103:8050/render.html>:TCP 连接超时:60:操作超时。
    • @Wine.Merchant 你启动了splash docker容器吗?谢谢。
    • 我打开 docker 并放入正确的行 $ docker run -p 8050:8050 scrapinghub/splash 然后这发生在 2015-08-21 15:22:19.651375 [-] 启动工厂
    • 我停止并重新启动了容器 scrapinghub/splash 但仍然超时。关于为什么会发生这种情况的更多观察?
    • 不,Telnet 控制台不会干扰 Splash。通过在浏览器中转到 192.168.59.103:8050 来测试您的 Splash 是否正常工作。如果不是,则 Splash 无法运行或无法访问,并且问题不在蜘蛛中。
    【解决方案2】:

    Alecxe 的非 JavaScript 替代方法是检查页面从何处手动加载内容,并在功能上添加 (see this SO question for more details).

    在这种情况下,我们得到以下结果:

    因此,对于 &lt;div class="shopthepost-widget" data-widget-id="708473"&gt;,执行 Javascript 以嵌入 url “widgets.rewardstyle.com/stps/708473.html”。

    您可以自己手动生成对这些 URL 的请求来处理这个问题:

    def parse(self, response):
        for widget in response.xpath('//div[@class="shopthepost-widget"]'):
            widget_id = widget.xpath('@data-widget-id').extract()[0]
            widget_url = "http://widgets.rewardstyle.com/stps/{id}.html".format(id=widget_id)
            yield Request(widget_url, callback=self.parse_widget)
    
    def parse_widget(self, response):
        for link in response.xpath('//a[contains(@class, "stp-product")]'):
            item = JavasItem()  # Name provided by author, see comments below
            item['link'] = links.xpath("@href").extract()
            yield item
    
        # Do whatever else you want with the opened page.
    

    如果您需要将这些小部件与它们所属的任何帖子/文章相关联,请通过 meta 将该信息传递到请求中。

    编辑: parse_widget() 已更新。它使用contains 来确定类,因为它的末尾有一个空格。您也可以使用 CSS 选择器,但这确实是您的选择。

    【讨论】:

    • 这似乎是一个更好的解决方案,无需依赖第三方。终端说它转到小部件的源页面,但我仍然无法存储页面中的项目。您能否举例说明如何使用 parse_widget 存储链接?
    • 我正在使用这个。或 sel 在 response.xpath('//a[@class="stp-control stp-left stp-hidden"]'): item = JavasItem() item['itemUrl'] = response.xpath('.// a/@href').extract() 产出项目
    • 您需要直接在目标链接上查看 HTML,而不是在内联加载它的页面上。当它通过 JS 加载时,该 JS 可以根据加载到的页面编辑/附加/删除类。由于 Scrapy 没有处理 JS 或看到这个,你会得到不同的结果。我更新了parse_widget 函数以提取页面上的所有链接。
    • 快速回复,非常感谢您提供的所有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 2020-03-16
    • 2017-01-01
    • 1970-01-01
    相关资源
    最近更新 更多