【问题标题】:Recursive crawling same page using javascript with scrapy and splash使用带有scrapy和splash的javascript递归爬取同一页面
【发布时间】:2016-11-07 09:42:32
【问题描述】:

我正在抓取一个有 javascript 的网站以转到下一页。我正在使用 splash 在第一页上执行我的 javascript 代码。但我能够进入第二页。但我无法进入 3,4,5.... 页面。仅一页后停止抓取。

我正在抓取的链接: http://59.180.234.21:8788/user/viewallrecord.aspx

代码:

import scrapy
from scrapy_splash import SplashRequest
from time import sleep


class MSEDCLSpider(scrapy.Spider):
    name = "msedcl_spider"
    scope_path = 'body > table:nth-child(11) tr > td.content_area > table:nth-child(4) tr:not(:first-child)'
    ref_no_path = "td:nth-child(1) ::text"
    title_path = "td:nth-child(2) ::text"
    end_date_path = "td:nth-child(5) ::text"
    fee_path = "td:nth-child(6) ::text"
    start_urls = ["http://59.180.234.21:8788/user/viewallrecord.aspx"]

    lua_src = """function main(splash)
        local url = splash.args.url
        splash:go(url)
        splash:wait(2.0)
        splash:runjs("document.querySelectorAll('#lnkNext')[0].click()")
        splash:wait(4.0)
        return {
            splash:html(),
        }
        end
        """

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(
                url,
                self.parse,
                endpoint='execute',
                method='POST',
                dont_filter=True,
                args={
                    'wait': 1.0,
                    'lua_source': self.lua_src,
                },
            )


    def parse(self, response):
        print response.status
        scopes = response.css('#page-info').extract()[0]
        print(response.url)
        print(scopes)

我是scrapy 和splash 的新手。请温柔一点。谢谢

【问题讨论】:

  • 主代码没有缩进问题。当我粘贴代码时,它被改变了。
  • 我认为您正在混合空格和制表符(至少在粘贴的代码中)。尝试使用所有空格(每个制表符 4 个空格)来格式化问题中的代码。
  • 问题不在于缩进。我以任何方式编辑帖子并修改它

标签: python scrapy web-crawler scrapy-splash scrapyjs


【解决方案1】:

我可以看到两个问题:

  1. 您没有提出这些请求。在 start_requests 中发出单个请求,响应在 self.parse 方法中解析,但从不发送对 3rd 和其他页面的请求。为此,您需要从 .parse 方法发送一些请求。

  2. 如果您修复 (1),那么您可能会面临下一个问题:Splash 不会在请求之间保持页面状态。将每个请求视为打开一个新的私有模式浏览器窗口并执行一些操作;这是设计使然。但是这个网站的问题是 URL 在页面之间不会改变,所以你不能只是开始例如从第 3 页开始,然后单击“下一页”。

但我认为有一些方法可以解决 (2)。也许您可以点击后获取页面html,然后使用splash:set_content将其加载到浏览器;您也可以保留 cookie - scrapy-splash README 中有一个示例;尽管该网站似乎并不依赖 cookie 进行分页。

另一种方法是编写一个脚本来加载所有页面,而不仅仅是下一页,然后将所有页面的内容返回给客户端。像这样的东西(未经测试):

function main(splash) 
    splash:go(splash.args.url)
    local pages = {splash:html()}
    for i = 2,100 do             
        splash:runjs("document.querySelectorAll('#lnkNext')[0].click()")            
        splash:wait(4)
        pages[i] = splash:html()
    end
    return pages
end

为此,您需要更大的超时值;您可能还必须使用更大的 --max-timeout 选项来启动 Splash。

【讨论】:

  • 感谢您的回答。第二种方法有什么缺点吗?比如性能、内存使用等,因为还有一些其他网站需要抓取超过 200 个页面。
  • @REDDYPRASAD 第二种方法更难监控和调试,并且您无法获得部分结果并在出现错误时继续(除非您以处理该问题的方式编写脚本)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 2019-05-28
  • 1970-01-01
相关资源
最近更新 更多