zoukankan      html  css  js  c++  java
  • 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。
  • 相关阅读:
    jquery 使用方法<转载>
    mybatis 使用resultMap实现数据库的操作
    myBatis 实现用户表增删查改操作<方法2 加入接口>(最终版)
    myBatis 实现用户表增删查改操作<方法1 没有使用接口的>(最终版)
    myBatis 实现用户表增操作(复杂型)
    MyBatis 用户表记录数查询
    SpringMVC 返回JSON数据
    springmvc中@PathVariable和@RequestParam的区别(百度收集)
    spring mvc文件上传和下载
    python 网络编程
  • 原文地址:https://www.cnblogs.com/yjybupt/p/13720035.html
Copyright © 2011-2022 走看看