使用 javascript 和 scrapy 和 splash 递归抓取同一页面
Recursive crawling same page using javascript with scrapy and splash
我正在抓取一个网站,其中 javascript 可以转到下一页。我正在使用 splash 在第一页上执行我的 javascript 代码。但是我能够转到第二页。但我无法转到第 3、4、5... 页。只爬了一页就停止了。
我正在爬的link:
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 的新手。请温柔点谢谢
我可以看到两个问题:
您没有提出这些请求。在 start_requests 中发出了一个请求,响应在 self.parse 方法中被解析,但是对第三页和其他页面的请求永远不会发送。为此,您需要从 .parse 方法发送一些请求。
如果您修复 (1),那么您可能会遇到下一个问题:Splash 不会在请求之间保持页面状态。将每个请求视为打开一个新的隐私模式浏览器 window 并执行一些操作;这是设计使然。但是这个网站的问题是 URL 不会在页面之间改变,所以你不能只是开始,例如从第 3 页开始,然后单击 "next" 页。
但我认为有一些方法可以解决 (2)。也许你可以在点击后得到页面html,然后使用splash:set_content将它加载到浏览器;你也可以保留 cookie——在 scrapy-splash README 中有一个例子;虽然这个网站似乎并不依赖 cookies 进行分页。
另一种方法是编写一个脚本来加载所有页面,而不仅仅是下一页,然后 returns 将所有页面的内容加载到客户端。像这样(未经测试):
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。
我正在抓取一个网站,其中 javascript 可以转到下一页。我正在使用 splash 在第一页上执行我的 javascript 代码。但是我能够转到第二页。但我无法转到第 3、4、5... 页。只爬了一页就停止了。
我正在爬的link: 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 的新手。请温柔点谢谢
我可以看到两个问题:
您没有提出这些请求。在 start_requests 中发出了一个请求,响应在 self.parse 方法中被解析,但是对第三页和其他页面的请求永远不会发送。为此,您需要从 .parse 方法发送一些请求。
如果您修复 (1),那么您可能会遇到下一个问题:Splash 不会在请求之间保持页面状态。将每个请求视为打开一个新的隐私模式浏览器 window 并执行一些操作;这是设计使然。但是这个网站的问题是 URL 不会在页面之间改变,所以你不能只是开始,例如从第 3 页开始,然后单击 "next" 页。
但我认为有一些方法可以解决 (2)。也许你可以在点击后得到页面html,然后使用splash:set_content将它加载到浏览器;你也可以保留 cookie——在 scrapy-splash README 中有一个例子;虽然这个网站似乎并不依赖 cookies 进行分页。
另一种方法是编写一个脚本来加载所有页面,而不仅仅是下一页,然后 returns 将所有页面的内容加载到客户端。像这样(未经测试):
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。