scrapy-splash 爬取网页

现在大部分网页内容都是由js动态加载得到,我们如果要使用scrapy静态爬取是爬取不到内容的,所以需要引入js渲染引擎去加载js,也就是splash。

然后还要使用一个包scrapy-splash,这个包调用了splash实例的接口,用来支持scrapy做爬虫。

Scrapy-Splash uses Splash HTTP API, so you also need a Splash instance.

 

1、启动splash实例

文档:https://splash.readthedocs.io/en/stable/

 

使用docker启动 docker run -p 8050:8050 scrapinghub/splash

 

2、安装scrapy-splash

pip install scrapy-splash

 

3、在爬虫中配置

https://pypi.org/project/scrapy-splash/

https://www.jianshu.com/p/9d0c53c97850

 

4、常见问题

① 浏览器可以直接访问localhost:8050访问splash实例,里面可以实施渲染Lua脚本,非常方便

② splash可以渲染Lua脚本语言,支持的操作可参照官网文档,这里举例一般爬虫需要的几个功能:访问网址、添加和获取cookie, 输入框,点击按钮,添加代理等

lua = """
function main(splash, args)
barcode = args.barcode
splash:on_request( #Register a function to be called before each HTTP request.
function(request)
request:set_proxy{'36.112.xxx.xxx', 25030 , username=nil, password=nil, type='HTTP'}
end)
splash:add_cookie{"ASP.NET_SessionId", "wptayq45fqbkbu55defy3245", path="/", domain="xxx.xx.com",httpOnly=True,secure=False}
assert(splash:go(args.url))
assert(splash:wait(2))

return {
html = splash:html(),
png = splash:png(),
cookies = splash:get_cookies(),
har = splash:har(),
}
end
"""

因为使用scrapy-splash,所以我们不能用scrapy的方法来操作cookies或者使用代理,这些都需要通过Lua脚本。

③ scrapy中使用yield SplashRequest
yield SplashRequest(url, endpoint='execute', args={'lua_source': lua,'barcode':barcode,'cookie':cookie},
cache_args=['lua_source'], callback=self.parse_data)
args里带上需要添加的cookie或者其他参数比如模拟登陆就带上username和psw
④ meta里有一些key是保留的关键词,不能用!!https://docs.scrapy.org/en/latest/topics/request-response.html?highlight=timeout#std-reqmeta-download_timeout
比如proxy, Download_Timeout之类的

⑤scrapy的顺序是,默认深度优先 即
DEPTH_PRIORITY = 0
SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleFifoDiskQueue'
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeues.FifoMemoryQueue'

但是如果层级只有1层就不影响了。
然后由于scrapy的多线程机制,在start_request当中,并不是完全顺序执行的(结果上来说,不是按顺序获得结果的,有的结果响应快,先返回,有的结果响应慢,过了很久才返回),因为它是非阻塞的。也就是如果某一个请求还没返回,他会执行下一个请求,
并且保持正在请求的数目,即并发数等于我们配置的CONCURRENT_REQUEST。
所以如果我们要保证一个请求结束才进行下一个请求,那么我们需要开单并发,然后运行多个scrapy(有点傻)。主要还是因为我们没有使用scrapy本身的ip代理,也就无法应用
CONCURRENT_REQUESTS_PER_IP = 1 这个参数,因为我们的ip代理是通过scrapy-splash执行的,如果不用splash,我们可以直接设置每个ip并发为1。
posted @ 2020-09-23 18:06  yjy888  阅读(305)  评论(0编辑  收藏  举报