2016-11-07 101 views
1

我正在爬行一个网站,它有JavaScript转到下一页。我正在使用splash在第一页上执行我的JavaScript代码。但我能够去第二页。但我无法去3,4,5 ....页面。爬网仅在一页后停止。递归爬行使用javascript与scrapy和splash的相同页面

的链接,我爬: 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和飞溅。请温柔。谢谢

+0

主代码中没有缩进问题。当我粘贴代码时,它被改变了。 –

+0

我认为你在混合空格和制表符(至少在粘贴的代码中)。尝试使用所有空格(每个选项卡4个空格)来格式化问题中的代码。 –

+0

问题不在于缩进。任何我编辑后的方式,并修改它 –

回答

2

我可以看到两个问题:

  1. 你最好不要让这些请求。在start_requests中发出一个请求,响应在self.parse方法中被解析,但对第三个和其他页面的请求从不发送。为此,您需要从.parse方法发送一些请求。

  2. 如果修复(1),那么你很可能会面临下一个问题:启动不保留请求之间的页面状态。将每个请求视为打开一个新的Private Mode浏览器窗口并执行一些操作;这是设计。但是这个网站的问题在于URL不会在页面之间改变,所以你不能只是开始从第3页开始,点击“下一页”。

但我认为有办法解决方法(2)。也许你可以点击后获取页面html,然后使用splash:set_content将其加载到浏览器;你也可以保存饼干 - 在scrapy-splash README中有一个例子;虽然它似乎并没有依靠cookies来进行分页。

另一种方式是写一个加载的所有页面,不仅翻页,然后返回所有网页到客户端的脚本的内容。像这样(未经测试):

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。

+0

感谢您的答案。第二种方法有什么缺点?如性能,内存使用等,因为有一些其他网站有超过200页的爬行。 –

+0

@REDDYPRASAD第二种方法很难监视和调试,并且如果发生错误,您将无法获得部分结果并继续执行(除非您已经以处理该脚本的方式编写脚本)。 –