Splash是一个JavaScript渲染服务,是一个带有HTTP API的轻量级浏览器,同时它对接了Python中的Twisted和QT库。
利用它,我们同样可以实现动态渲染页面的抓取。

1. 功能介绍和基本实例

  1. ### Splash的使用
  2. '''
  3. Splash是一个JavaScript渲染服务,是一个带有HTTP API的轻量级浏览器,同时它对接了Python中的Twisted和QT库。
  4. 利用它,我们同样可以实现动态渲染页面的抓取。
  5. '''
  6.  
  7. ## 功能介绍
  8. # 1.异步方式处理多个网页渲染过程
  9. # 2.获取渲染后页面的源代码或截图
  10. # 3.通过关闭图片渲染或者使用Adblock规则来加快页面渲染速度
  11. # 4.可执行特定的JavaScript脚本
  12. # 5.可通过Lua脚本来控制页面渲染过程
  13. # 6.获取渲染的详细过程并通过HAR(HTTP Archive)格式呈现
  14.  
  15. ## 基本实例
  16. function main(splash, args)
  17. splash:go("http://www.baidu.com")
  18. splash:wait(0.5)
  19. local title = splash:evaljs("document.title")
  20. return {
  21. title = title
  22. }
  23. end

2. Splash用lua脚本爬取网页的基本使用介绍

  2.1 异步处理

  1. ## 异步处理
  2. # ipairs,为集合元素进行编号(编号从1开始),类似于python的enumerate
  3. # lua脚本语言中字符串拼接用 ..
  4. # splash:wait()类似于python中的time.sleep()
  5. # 当Splash执行wait方法时,它会转而去处理其他任务,等到指定时间结束后再回来进行继续处理
  6.  
  7. function main(splash, args)
  8. local example_urls = {"www.baidu.com", "www.taobao.com", "www.zhihu.com"}
  9. local urls = args.urls or example_urls
  10. local results = {}
  11. for index, url in ipairs(urls) do
  12. local ok, reason = splash:go("http://" .. url)
  13. if ok then
  14. splash:wait(2)
  15. results[url] = splash:png()
  16. end
  17. end
  18. return results
  19. end

  2.2 Splash的对象属性

2.2.1 args,main方法中的第二个args属性即加载到splash中,即 args.url == splash.args.url

2.2.2 js_enabled,页面JavaScript的执行开关,默认为true

  1. ## js_enabled,页面JavaScript的执行开关,默认为True
  2. function main(splash, args)
  3. splash:go("http://www.baidu.com")
  4. splash.js_enabled = False
  5. local title = splash:evaljs("document.title")
  6. return {
  7. title = title
  8. }
  9. end
  10.  
  11. '''
  12. 执行结果:
  13. {
  14. "error": 400,
  15. "type": "ScriptError",
  16. "description": "Error happened while executing Lua script",
  17. "info": {
  18. "type": "SPLASH_LUA_ERROR",
  19. "message": "[string \"function main(splash, args)\r...\"]:3: setAttribute(self, QWebSettings.WebAttribute, bool): argument 2 has unexpected type 'NoneType'",
  20. "source": "[string \"function main(splash, args)\r...\"]",
  21. "line_number": 3,
  22. "error": "setAttribute(self, QWebSettings.WebAttribute, bool): argument 2 has unexpected type 'NoneType'"
  23. }
  24. }
  25. '''

2.2.3 resource_timeout,页面加载超时时间,单位是秒

  1. ## resource_timeout,页面加载超时时间,单位是秒
  2. function main(splash, args)
  3. splash.resource_timeout = 0.01
  4. assert(splash:go("http://www.baidu.com"))
  5. return splash:png()
  6. end
  7.  
  8. '''
  9. {
  10. "error": 400,
  11. "type": "ScriptError",
  12. "description": "Error happened while executing Lua script",
  13. "info": {
  14. "source": "[string \"function main(splash, args)\r...\"]",
  15. "line_number": 3,
  16. "error": "network5",
  17. "type": "LUA_ERROR",
  18. "message": "Lua error: [string \"function main(splash, args)\r...\"]:3: network5"
  19. }
  20. }
  21. '''

2.2.4 images_enabled,页面图片是否加载,默认为true

  1. ## images_enabled,页面图片是否加载,默认为True
  2. ## 禁用图片可以节省网络流量以及加快网页加载速度,当加载页面可能会影响JavaScript的渲染
  3. ## Splash使用了缓存,即访问过一次页面的图片,即使禁用页面图片加载后,依旧可以访问到缓存中的图片
  4. ## 如下面示例,返回的phg页面就不会带有图片
  5.  
  6. function main(splash, args)
  7. splash.images_enabled = false
  8. assert(splash:go("https://www.bilibili.com/"))
  9. return {
  10. png = splash:png()
  11. }
  12. end

2.2.4 plugins_enabled,控制浏览器插件(如flash等)是否开启,默认为false

2.2.5 scroll_position,控制页面的上下左右滚动,用x定位左右,y定位上下;如下示例,定位到y=800的位置

  1. ## scroll_position,控制页面的上下左右滚动,用x定位左右,y定位上下;如下示例,定位到y=800的位置
  2.  
  3. function main(splash, args)
  4. assert(splash:go("https://www.mi.com"))
  5. splash.scroll_position = {y = 800}
  6. return {png = splash:png()}
  7. end

2.3 Splash对象的方法

2.3.1 go方法,用来请求某个链接,可以模拟get和post请求,同时传入请求头、表单等数据,赋值传入变量时用{}

  1. ## go方法,用来请求某个链接,可以模拟get和post请求,同时传入请求头、表单等数据,赋值传入变量时用{}
  2. ## go方法有2个返回值,ok和reason,ok为空代表网页加载出现错误,此时reason变量中包含错误原因
  3. # url:请求的URL
  4. # baseurl:可选参数,默认为空,表示自愿加载的相对路径
  5. # headers:可选参数,默认为空,请求头
  6. # http_method:可选参数,默认为get,可以支持post
  7. # body:可选参数,默认为空,发post请求时的表单数据,传入的数据内容类型为json
  8. # formdata:可选参数,默认为空,发post请求时的表单数据,传入的数据内容类型为x-www-form-urlencoded
  9.  
  10. function main(splash, args)
  11. local ok, reason = splash:go{url="http://httpbin.org/post", http_method="POST", body="name=dmr"}
  12. if ok then
  13. return splash:html()
  14. end
  15. end

2.3.2 wait方法,控制页面的等待时间,可以传入多值,赋值传入变量时用{}

  1. ## wait方法,控制页面的等待时间,可以传入多值,赋值传入变量时用{}
  2. ## 同样有2个返回值,ok和reason,ok为空代表网页加载出现错误,此时reason变量中包含错误原因
  3. ## ok, reason = splash:go{time, cancel_on_redirect=false, cancel_on_error=false}
  4. # time:等待的秒数
  5. # cancel_on_redirect:可选参数,默认为false,表示如果发生了重定向则停止等待并返回重定向结果
  6. # cancel_on_error:可选参数,默认为false,表示如果发生了错误就停止等待
  7.  
  8. function main(splash, args)
  9. local ok, reason = splash:go("http://www.mi.com")
  10. splash:wait(2)
  11. if ok then
  12. return splash:html()
  13. end
  14. end

2.3.3 JavaScript等的操作方法

  1. ## jsfunc方法,可以直接调用JavaScript定义的方法,所调用的方法要用双括号包围
  2. ## 如下示例,通过构造JavaScript方法来获取访问页面的title和div数量并返回
  3. function main(splash, args)
  4. local get_div_count = splash:jsfunc([[
  5. function(){
  6. var title = document.title;
  7. var body = document.body;
  8. var divs = body.getElementsByTagName('div');
  9. var div_count = divs.length;
  10. return {div_count, title};
  11. }
  12. ]])
  13. ok, reason = splash:go("https://www.mi.com")
  14. result = get_div_count()
  15. return ("This page'title is %s, there are %s divs"):format(result.title, result.div_count)
  16. end
  17.  
  18. ## evaljs方法,可以执行JavaScript代码并返回最后一条JavaScript的返回结果
  19. ## 如下示例,只返回最后一条JavaScript语句的执行结果
  20. function main(splash, args)
  21. splash:go("https://www.mi.com")
  22. result = splash:evaljs("document.title;document.body.getElementsByTagName('div').length;")
  23. return result
  24. end
  25.  
  26. ## runjs方法,可以执行JavaScript代码,与evaljs类似,但是更偏向于执行某些动作或声明某些方法
  27. ## 如下示例,用runjs方法构造了一个JavaScript定义的方法,然后用evaljs执行此方法获取返回结果
  28. function main(splash, args)
  29. splash:go("https://www.mi.com")
  30. splash:runjs("fofo = function(){return 'dmr'}")
  31. result = splash:evaljs('fofo()')
  32. return result
  33. end
  34.  
  35. ## autoload方法,可以设置每个页面访问时自动加载的对象,在Lua语言中nil相当于python的None
  36. ## ok, reason = splash:autoload{source_or_url, source=nil, url=nil}
  37. # source_or_url:JavaScript代码或JavaScript库链接
  38. # source:JavaScript代码
  39. # url:JavaScript库链接
  40. # 示例1,通过构造一个get_path_title对象方法,用evaljs调用执行获取返回结果,在这里与runjs类似,不过构造方法需要用[]中括号
  41. function main(splash, args)
  42. splash:autoload([[
  43. function get_path_title(){
  44. return document.title;
  45. }
  46. ]])
  47. splash:go("https://www.mi.com")
  48. result = splash:evaljs('get_path_title()')
  49. return result
  50. end
  51.  
  52. # 示例2,用autoload加载jquery方法库
  53. function main(splash, args)
  54. assert(splash:autoload("https://code.jquery.com/jquery-2.2.4.min.js"))
  55. assert(splash:go("https://www.baidu.com"))
  56. local version = splash:evaljs("$.fn.jquery")
  57. return 'Version is '..version
  58. end

2.3.4 call_later方法,设置定时任务进行延时执行,并且可以在执行前通过cancel()方法重新执行定时任务

  1. ## call_later方法,设置定时任务进行延时执行,并且可以在执行前通过cancel()方法重新执行定时任务
  2. # 如下示例,构造一个timer定时任务,当访问页面时,等待0.2秒获取页面的截图,再等待1秒后获取页面的截图
  3. # 第一次获取页面的截图页面还没加载出来,所以获取到的是空白页
  4.  
  5. function main(splash, args)
  6. local pngs = {}
  7. local timer = splash:call_later(function()
  8. pngs['a'] = splash:png()
  9. splash:wait(1)
  10. pngs['b'] = splash:png()
  11. end, 0.2)
  12. splash:go("https://www.mi.com")
  13. return pngs
  14. end

2.3.5 http_get方法,模拟发送http的get请求

  1. ## http_get方法,模拟发送http的get请求
  2. ## response = splash:http_get{url, headers=nil, follow_redirects=true}
  3. # url:请求URL
  4. # headers:可选参数,默认为空,请求头
  5. # follwo_redirects:可选参数,表示是否启动自动重定向,默认为true
  6.  
  7. function main(splash, args)
  8. local t = require("treat")
  9. local response = splash:http_get("https://www.taobao.com")
  10. if response.status == 200 then
  11. return {
  12. b_html = response.body,
  13. html = t.as_string(response.body),
  14. url = response.url,
  15. status = response.status,
  16. }
  17. end
  18. end

2.3.6 http_post方法,模拟发送http的post请求,与http_get方法类似,不过多个body表单参数

  1. ## http_post方法,模拟发送http的post请求,与http_get方法类似,不过多个body表单参数
  2. ## response = splash:http_get{url, headers=nil, follow_redirects=true, body=nil}
  3. # url:请求URL
  4. # headers:可选参数,默认为空,请求头
  5. # follwo_redirects:可选参数,表示是否启动自动重定向,默认为true
  6. # body:可选参数,默认为空,表单数据
  7. # 如下示例,将表单数据提交到了json中
  8.  
  9. function main(splash, args)
  10. local t = require("treat")
  11. local json = require("json")
  12. local response = splash:http_post{
  13. "http://httpbin.org/post",
  14. body=json.encode({name="dmr"}),
  15. headers={["content-type"]="application/json"}
  16. }
  17. if response.status == 200 then
  18. return {
  19. 'response',
  20. b_html = response.body,
  21. html = t.as_string(response.body),
  22. url = response.url,
  23. status = response.status,
  24. }
  25. end
  26. end

2.3.7 set_content方法,用来设置页面的内容

  1. ## set_content方法,用来设置页面的内容
  2. ## 如下示例,可以看到页面中有dmr的内容
  3.  
  4. function main(splash, args)
  5. assert(splash:set_content("<h1>dmr</h1>"))
  6. return splash:png()
  7. end

2.3.8 html方法,用来获取网页的源代码

  1. ## html方法,用来获取网页的源代码
  2.  
  3. function main(splash, args)
  4. assert(splash:go("https://www.baidu.com"))
  5. return splash:html()
  6. end

2.3.9 png方法和jpeg方法,用来获取网页页面png格式或jpeg格式的截图

  1. ## png方法和jpeg方法,用来获取网页页面png格式或jpeg格式的截图
  2.  
  3. function main(splash, args)
  4. assert(splash:go("https://www.baidu.com"))
  5. return {
  6. png = splash:png(),
  7. jpeg = splash:jpeg()
  8. }
  9. end

2.3.10 har方法,用来获取页面加载过程描述

  1. ## har方法,用来获取页面加载过程描述
  2.  
  3. function main(splash, args)
  4. assert(splash:go("https://www.baidu.com"))
  5. return {
  6. har = splash:har()
  7. }
  8. end

2.3.11 url方法,用来获取当前正在访问页面的url

  1. ## url方法,用来获取当前正在访问页面的url
  2.  
  3. function main(splash, args)
  4. assert(splash:go("https://www.baidu.com"))
  5. return {url = splash:url()}
  6. end

2.3.12 Cookies操作

  1. ## get_cookies方法,用来获取当前页面的cookies
  2. function main(splash, args)
  3. assert(splash:go("https://www.baidu.com"))
  4. return {cookies = splash:get_cookies()}
  5. end
  6.  
  7. ## add_cookie方法,为当前页面添加cookie
  8. ## splash:add_cookie{name, value, path=nil, domain=nil, expires=nil, httpOnly=nil, secure=nil}
  9. function main(splash, args)
  10. splash:add_cookie{'name', 'dmr'}
  11. assert(splash:go("https://www.baidu.com"))
  12. return {cookies = splash:get_cookies()}
  13. end
  14.  
  15. ## clear_cookies方法,清楚所有的cookies
  16. function main(splash, args)
  17. splash:add_cookie{'name', 'dmr'}
  18. assert(splash:go("https://www.baidu.com"))
  19. splash:clear_cookies()
  20. return {cookies = splash:get_cookies()}
  21. end

2.3.13 浏览器视图操作

  1. ## get_viewport_size方法,用来获取当前页面的大小,即宽高
  2. function main(splash, args)
  3. assert(splash:go("https://www.taobao.com"))
  4. return splash:get_viewport_size()
  5. end
  6.  
  7. ## set_viewport_size方法,设置当前浏览器页面的大小,即宽高
  8. function main(splash, args)
  9. splash:set_viewport_size(400, 400)
  10. assert(splash:go("https://www.taobao.com"))
  11. return splash:png()
  12. end
  13.  
  14. ## set_viewport_full方法,用来设置浏览器全屏显示
  15. function main(splash, args)
  16. splash:set_viewport_full()
  17. assert(splash:go("https://www.taobao.com"))
  18. return splash:png()
  19. end

2.3.14 set_user_agent方法,用来设置浏览器的User-Agent

  1. ## set_user_agent方法,用来设置浏览器的User-Agent
  2.  
  3. function main(splash, args)
  4. splash:set_user_agent('Splash')
  5. assert(splash:go("https://httpbin.org/get"))
  6. return splash:html()
  7. end

2.3.15 set_custom_headers方法,可以用来设置请求头

  1. ## set_custom_headers方法,可以用来设置请求头
  2.  
  3. function main(splash, args)
  4. splash:set_custom_headers({
  5. ["User-Agent"] = "Splash",
  6. ["Host"] = "Splash.org"
  7. })
  8. assert(splash:go("https://httpbin.org/get"))
  9. return splash:html()
  10. end

2.3.16 select方法,查找符合条件的第一个节点,用的是CSS选择器

  1. ## select方法,查找符合条件的第一个节点,用的是CSS选择器
  2.  
  3. function main(splash, args)
  4. assert(splash:go("https://www.taobao.com"))
  5. input = splash:select("#q")
  6. input:send_text("数码")
  7. splash:wait(2)
  8. return splash:jpeg()
  9. end

2.3.17 select_all方法,查找符合条件的所有节点,用的是CSS选择器

  1. ## select_all方法,查找符合条件的所有节点,用的是CSS选择器
  2.  
  3. function main(splash, args)
  4. local treat = require("treat")
  5. assert(splash:go("https://movie.douban.com/top250"))
  6. assert(splash:wait(1))
  7. local items = splash:select_all(".inq")
  8. local sum = {}
  9. for index, item in ipairs(items) do
  10. sum[index] = item.node.innerHTML
  11. end
  12. return {
  13. obj1 = sum,
  14. obj2 = treat.as_array(sum)
  15. }
  16. end

2.3.18 mouse_click方法,模拟鼠标点击操作

  1. ## mouse_click方法,模拟鼠标点击操作
  2. ## 1.传入x和y进行点击操作
  3. ## 2.查找到相关节点,调用此方法进行点击操作
  4.  
  5. function main(splash, args)
  6. splash:go("https://www.baidu.com")
  7. input = splash:select("#kw")
  8. input:send_text("Python")
  9. splash:wait(1)
  10. search = splash:select('#su')
  11. search:mouse_click()
  12. splash:wait(2)
  13. return splash:png()
  14. end

3. Splash API的调用,以Python为例

    官方API文档:https://splash.readthedocs.io/en/stable/api.html

  3.1 render.html页面,此接口用于获取JavaScript渲染的页面的HTML代码

  1. ## render.html页面,此接口用于获取JavaScript渲染的页面的HTML代码
  2. ## 获取百度页面源代码url示例:http://localhost:8050/render.html?url=https://www.baidu.com
  3. # 示例,通过调用render.html页面获取百度的源代码并且设置等待时间为4秒
  4. import requests
  5.  
  6. url = 'http://10.0.0.100:8050/render.html?url=https://www.baidu.com&wait=4'
  7. response = requests.get(url)
  8. print(response.text)

  3.2 render.png和render.jpeg,此接口获取网页截图, 返回的是二进制数据

  1. ## render.png和render.jpeg,此接口获取网页截图,返回的是二进制数据
  2. ## 配置参数:url,wait,width,height
  3. ## render.jpeg多了个参数quality,用来调整图片的质量,取值1-100,默认值为75,应尽量避免取95以上的数值
  4. ## url示例:http://localhost:8050/render.png?url=https://www.baidu.com&wait=2&width=400&height=400
  5. # 示例,通过render.png接口获取页面宽400高400的页面截图并保存到文件中
  6. import requests
  7.  
  8. url = 'http://10.0.0.100:8050/render.png?url=https://www.taobao.com&wait=5&width=1000&height=700'
  9. url2 = 'http://10.0.0.100:8050/render.jpeg?url=https://www.taobao.com&wait=5&width=1000&height=700&quality=90'
  10. response = requests.get(url)
  11. with open('taobao.png', 'wb') as f:
  12. f.write(response.content)
  13. response2 = requests.get(url2)
  14. with open('taobao.jpeg', 'wb') as f:
  15. f.write(response2.content)

  3.3 render.har,此接口用来获取页面加载的HAR数据,返回的是json格式的数据

  1. ## render.har,此接口用来获取页面加载的HAR数据,返回的是json格式的数据
  2. ## url示例:http://localhost:8050/render.har?url=https://www.baidu.com&wait=2
  3. import requests, json
  4.  
  5. url = 'http://10.0.0.100:8050/render.har?url=https://www.baidu.com&wait=2'
  6. response = requests.get(url)
  7. print(response.content)
  8. with open('har.text', 'w') as f:
  9. f.write(json.dumps(json.loads(response.content), indent=2))

  3.4 render.json,此接口包含了前面接口的所有功能,返回结果是json格式

  1. ## render.json,此接口包含了前面接口的所有功能,返回结果是json格式
  2. ## url示例:http://localhost:8050/render.json?url=https://www.baidu.com&html=1&png=1&jpeg=1&har=1
  3. ## 默认返回:{'url': 'https://www.baidu.com/', 'requestedUrl': 'https://www.baidu.com/', 'geometry': [0, 0, 1024, 768], 'title': '百度一下,你就知道'}
  4. ## 通过将html、png、jpeg、har参数置为1获取相关的页面数据
  5. import requests, json
  6.  
  7. url = 'http://10.0.0.100:8050/render.json?url=https://www.baidu.com&html=1&png=1&jpeg=1&har=1'
  8. response = requests.get(url)
  9.  
  10. data = json.loads(response.content)
  11. print(data)
  12. print(data.get('html'))
  13. print(data.get('png'))
  14. print(data.get('jpeg'))
  15. print(data.get('har'))

  3.5 execute,功能强大,此接口可实现与Lua脚本的对接,实现交互性操作

  1. ## execute,此接口可实现与Lua脚本的对接,可实现交互性操作
  2. ## url示例:http://localhost:8050/execute?lua_source=
  3. # 示例1,简单示例,返回lua的执行结果
  4. from urllib.parse import quote
  5. import requests
  6.  
  7. lua = '''
  8. function main(splash)
  9. return 'hello'
  10. end
  11. '''
  12. url = 'http://10.0.0.100:8050/execute?lua_source=%s' % quote(lua)
  13. response = requests.get(url)
  14. print(response.text)
  15. # 示例2,通过execute执行lua脚本获取页面的url,png,html
  16. from urllib.parse import quote
  17. import requests, json
  18.  
  19. lua = '''
  20. function main(splash)
  21. splash:go('https://www.baidu.com')
  22. splash:wait(2)
  23. return {
  24. html = splash:html(),
  25. png = splash:png(),
  26. url = splash:url()
  27. }
  28. end
  29. '''
  30. url = 'http://10.0.0.100:8050/execute?lua_source=%s' % quote(lua)
  31. response = requests.get(url)
  32. print(type(response.text), response.text)
  33. dic = json.loads(response.text)
  34. print(type(dic), len(dic), dic.keys())

4. Splash通过Nginx配置负载均衡基本思路

  1. 1. 配置多台splash服务器
  2.  
  3. 2. 选中其中一台或者另起一台服务器安装nginx服务
  4.  
  5. 3. 配置nginx.conf配置文件,内容大致为:
  6. http {
  7. upstream splash {
  8. least_conn; #最少连接负载均衡,不配置这进行轮询,ip_hash配置ip散列负载均衡
  9. server 10.0.0.100:8050;
  10. server 10.0.0.99:8050;
  11. server 10.0.0.98:8050;
  12. server 10.0.0.97:8050;
  13. }
  14. server {
  15. listen 8050;
  16. location / {
  17. proxy_pass http://splash; # 指定域名
  18. auth_basic "Restricted"; # 配置认证
  19. auth_basic_user_file /etc/nginx/conf.d/.htpasswd; # 指定认证的用户密码文件
  20. }
  21. }
  22. }
  23.  
  24. 4. 如不配置认证,直接重载nginxsudo nginx -s reload;配置了认证则需要构建密码文件,建议用htpasswd命令构建,在重载nginx
  25.  
  26. 5. 进行相关测试,测试脚本
  27. from urllib.parse import quote
  28. import requests, re
  29.  
  30. lua = '''
  31. function main(splash)
  32. local treat = require('treat')
  33. response = splash:http_get('https://www.baidu.com')
  34. return treat.as_string(response.body)
  35. end
  36. '''
  37. url = 'http://splash/execute?lua_source=%s' % quote(lua)
  38. response = requests.get(url)
  39. ip = re.search('(\d+\.\d+\.\d+\.\d+)', response.text).group(1)
  40. print(ip)

爬虫动态渲染页面爬取之Splash的介绍和使用的更多相关文章

  1. 爬虫动态渲染页面爬取之selenium驱动chrome浏览器的使用

    Selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样,可以用其进行网页动态渲染页面的爬取. 支持的浏览器包括IE(7, 8, 9, 10 ...

  2. 动态渲染页面爬取-Selenium & Splash

    模拟浏览器的动机 JS动态渲染的页面不止Ajax一种 很多网页的Ajax接口含有加密参数,分析其规律的成本过高 通过对浏览器运行方式的模拟,我们将做到:可见即可爬 Python中常用的模拟浏览器运行的 ...

  3. 动态渲染页面爬取(Python 网络爬虫) ---Selenium的使用

    Selenium 的使用 Selenium 是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击.下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬.对于一些JavaS ...

  4. 爬虫之Selenium 动态渲染页面爬取

    Selenim 是一个自动化测试工具,可以利用它驱动浏览器执行特定的动作,如点击.下拉等操作,同时可以获取浏览器当前呈现的页面的源代码,做到可见及可爬 1.使用流程 1)声明浏览器对象 Seleniu ...

  5. python3编写网络爬虫14-动态渲染页面爬取

    一.动态渲染页面爬取 上节课我们了解了Ajax分析和抓取方式,这其实也是JavaScript动态渲染页面的一种情形,通过直接分析Ajax,借助requests和urllib实现数据爬取 但是javaS ...

  6. [Python3网络爬虫开发实战] 7-动态渲染页面爬取

    在前一章中,我们了解了Ajax的分析和抓取方式,这其实也是JavaScript动态渲染的页面的一种情形,通过直接分析Ajax,我们仍然可以借助requests或urllib来实现数据爬取. 不过Jav ...

  7. 【图文详解】scrapy爬虫与动态页面——爬取拉勾网职位信息(2)

    上次挖了一个坑,今天终于填上了,还记得之前我们做的拉勾爬虫吗?那时我们实现了一页的爬取,今天让我们再接再厉,实现多页爬取,顺便实现职位和公司的关键词搜索功能. 之前的内容就不再介绍了,不熟悉的请一定要 ...

  8. 爬虫系列5:scrapy动态页面爬取的另一种思路

    前面有篇文章给出了爬取动态页面的一种思路,即应用Selenium+Firefox(参考<scrapy动态页面爬取>).但是selenium需要运行本地浏览器,比较耗时,不太适合大规模网页抓 ...

  9. 爬虫系列4:scrapy技术进阶之多页面爬取

    多页面爬取有两种形式. 1)从某一个或者多个主页中获取多个子页面的url列表,parse()函数依次爬取列表中的各个子页面. 2)从递归爬取,这个相对简单.在scrapy中只要定义好初始页面以及爬虫规 ...

随机推荐

  1. 用Python画如此漂亮的专业插图 ?简直So easy!

    本文整理自知乎问答,仅用于学术分享,著作权归作者所有.如有侵权,请联系我删文处理.多多转发,多多学习! 方法一 强烈推荐 Python 的绘图模块 matplotlib: python plottin ...

  2. 攻防世界 杂项 9.a_good_idea

    题目描述: 汤姆有个好主意 解题思路: 首先按照隐写思路找了一下没找到flag,接着使用winhex打开图片,发现图片里面又包含了一张图片,然后马上改了一下后缀为zip, 解压后发现里面有:hint. ...

  3. Nginx(三):Linux环境(Ubuntu)下Nginx的安装

    Nginx 是一位俄罗斯人 Igor Sysoev(伊戈尔·塞索斯夫)编写的一款高性能HTTP和反向代理服务器. Nginx 主要是有C编写的,安装Nginx需要GCC编译器(GNU Compiler ...

  4. POJ 1274 The Perfect Stall(二分图最大匹配)

    题意: N头牛M个牛棚,每只牛都有它自己指定的若干个它愿意呆的牛棚. 每个牛棚最多呆一头牛. 问最多可以满足多少头牛的愿望. 思路: 裸二分图最大匹配. 代码: int n,m; vector< ...

  5. Latex使用CJK包添加字体

    最近写论文时有个中文期刊提供的LaTeX模板使用CJK宏包,大致是这样的: \documentclass{article} \usepackage{CJK} \begin{document} \beg ...

  6. selenium2.x 与 selenium3.x 最大区别

    一.selenium2.x 与 selenium3.x 最大区别 (1) 从3.0版本selenium开始使用火狐浏览器完成web自动化就需要用到驱动包了. (2) 而2.0版本的selenium使用 ...

  7. vue禁用浏览器回退

    解决方案 mounted() { history.pushState(null, null, document.URL) window.addEventListener('popstate', () ...

  8. 用户登录成功后重新获取新的Session

    HttpSession session = request.getSession();            // 用来存储原sessionde的值            ConcurrentHash ...

  9. 大一C语言学习笔记(7)---指针篇--什么是指针?什么是指针变量?取地址符“&”的作用是什么?地址运算符“*”的作用是什么,怎么理解两者?

    "指针是C语言的灵魂"这句话一开始我没怎么明白,现在接触了指针,终于知道为什么这么说了,因为....难,真难:下面说一下我对这句话的见解: C语言拥有着其他语言所没有的特性---直 ...

  10. 问题 K: 找点

    题目描述 上数学课时,老师给了LYH一些闭区间,让他取尽量少的点,使得每个闭区间内至少有一个点.但是这几天LYH太忙了,你们帮帮他吗? 输入 多组测试数据. 每组数据先输入一个N,表示有N个闭区间(N ...