人生苦短,我用 Python

前文传送门:

小白学 Python 爬虫(1):开篇

小白学 Python 爬虫(2):前置准备(一)基本类库的安装

小白学 Python 爬虫(3):前置准备(二)Linux基础入门

小白学 Python 爬虫(4):前置准备(三)Docker基础入门

小白学 Python 爬虫(5):前置准备(四)数据库基础

小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装

小白学 Python 爬虫(7):HTTP 基础

小白学 Python 爬虫(8):网页基础

小白学 Python 爬虫(9):爬虫基础

小白学 Python 爬虫(10):Session 和 Cookies

小白学 Python 爬虫(11):urllib 基础使用(一)

小白学 Python 爬虫(12):urllib 基础使用(二)

小白学 Python 爬虫(13):urllib 基础使用(三)

小白学 Python 爬虫(14):urllib 基础使用(四)

小白学 Python 爬虫(15):urllib 基础使用(五)

小白学 Python 爬虫(16):urllib 实战之爬取妹子图

小白学 Python 爬虫(17):Requests 基础使用

小白学 Python 爬虫(18):Requests 进阶操作

小白学 Python 爬虫(19):Xpath 基操

小白学 Python 爬虫(20):Xpath 进阶

小白学 Python 爬虫(21):解析库 Beautiful Soup(上)

小白学 Python 爬虫(22):解析库 Beautiful Soup(下)

小白学 Python 爬虫(23):解析库 pyquery 入门

小白学 Python 爬虫(24):2019 豆瓣电影排行

小白学 Python 爬虫(25):爬取股票信息

小白学 Python 爬虫(26):为啥买不起上海二手房你都买不起

小白学 Python 爬虫(27):自动化测试框架 Selenium 从入门到放弃(上)

小白学 Python 爬虫(28):自动化测试框架 Selenium 从入门到放弃(下)

小白学 Python 爬虫(29):Selenium 获取某大型电商网站商品信息

小白学 Python 爬虫(30):代理基础

小白学 Python 爬虫(31):自己构建一个简单的代理池

小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门

小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)

小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)

小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器

小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware

小白学 Python 爬虫(37):爬虫框架 Scrapy 入门基础(五) Spider Middleware

小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline

引言

Splash 是一种 JavaScript 渲染服务,是一个带有 HTTP API 的轻量级浏览器,同时它对接了 Python3 中的 Twisted 和 QT 库。

通过它,我们同样可以实现动态渲染页面的抓取。

Github:https://github.com/scrapy-plugins/scrapy-splash

Splash 官方文档:http://splash.readthedocs.io

功能说明:

  • 并行处理多个网页;
  • 获取 HTML 结果和/或获取屏幕截图;
  • 关闭图片或使用 Adblock Plus 规则来加快渲染速度;
  • 在页面上下文中执行自定义 JavaScript;
  • 编写 Lua 浏览脚本 ;
  • 在 Splash-Jupyter Notebook 中开发 Splash Lua 脚本。
  • 以 HAR 格式获取详细的渲染信息。

安装

安装 Splash 主要有两个部分,一个是 Splash 服务的安装,具体是通过Docker,安装之后,会启动一个 Splash 服务。另外一个是 Scrapy-Splash 的 Python 库的安装,安装之后即可在 Scrapy 中使用 Splash 服务。

在 Docker 中安装 Splash 服务,命令如下:

docker run -p 8050:8050 scrapinghub/splash

理论上看到如下内容,就证明安装成功了。

2020-01-10 13:09:41+0000 [-] Log opened.
2020-01-10 13:09:41.824978 [-] Xvfb is started: ['Xvfb', ':1196586140', '-screen', '0', '1024x768x24', '-nolisten', 'tcp']
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-splash'
2020-01-10 13:09:42.153188 [-] Splash version: 3.4
2020-01-10 13:09:42.376664 [-] Qt 5.13.1, PyQt 5.13.1, WebKit 602.1, Chromium 73.0.3683.105, sip 4.19.19, Twisted 19.7.0, Lua 5.2
2020-01-10 13:09:42.376820 [-] Python 3.6.8 (default, Oct 7 2019, 12:59:55) [GCC 8.3.0]
2020-01-10 13:09:42.376898 [-] Open files limit: 1048576
2020-01-10 13:09:42.376965 [-] Can't bump open files limit
2020-01-10 13:09:42.394903 [-] proxy profiles support is enabled, proxy profiles path: /etc/splash/proxy-profiles
2020-01-10 13:09:42.395050 [-] memory cache: enabled, private mode: enabled, js cross-domain access: disabled
2020-01-10 13:09:42.594670 [-] verbosity=1, slots=20, argument_cache_max_entries=500, max-timeout=90.0
2020-01-10 13:09:42.594909 [-] Web UI: enabled, Lua: enabled (sandbox: enabled), Webkit: enabled, Chromium: enabled
2020-01-10 13:09:42.595245 [-] Site starting on 8050
2020-01-10 13:09:42.595341 [-] Starting factory <twisted.web.server.Site object at 0x7f26e5414fd0>
2020-01-10 13:09:42.595541 [-] Server listening on http://0.0.0.0:8050

这时我们打开浏览器直接访问 http://localhost:8050 ,就能看到 Splash 的主页:

接下来安装 Scrapy-Splash 的 Python 库,这个就比较简单了,一个命令搞定:

pip install scrapy-splash

试用

打开 Splash 的主页,可以看到输入框中默认访问的是 http://google.com ,我们这里换成度娘的首页看下:

可以看到,网页的返回结果呈现了渲染截图、 HAR 加载统计数据、网页的源代码。

通过 HAR 的结果可以看到, Splash 执行了整个网页的渲染过程,包括 CSS 、 JavaScript 的加载等过程,呈现的页面和我们在浏览器中得到的结果完全一致。

点击上方的 Script 按钮,可以看到一段脚本,如下:

function main(splash, args)
assert(splash:go(args.url))
assert(splash:wait(0.5))
return {
html = splash:html(),
png = splash:png(),
har = splash:har(),
}
end

这里其实是一段 Lua 脚本, Splash 的整个渲染都是由这个 Lua 脚本进行控制的。

虽然我们并不清楚 Lua 脚本的语法,但是看了这个代码,也应该能大致猜测出来首先是使用 go() 访问了 url ,然后使用 wait() 等待了 0.5 秒。最后返回了页面的 html 源码,png 的截图和 har 的一些数据。

Splash Lua API

我们来简单的了解一下 Splash Lua 的一些内置的 API ,更多的内容可以访问文档获得,小编这里主要介绍一下有关页面操作的 API 。

Splash Lua API 文档地址:https://splash.readthedocs.io/en/stable/scripting-overview.html

导航

延迟

从页面中提取信息

截图

与页面互动

HTTP请求

  • splash:http_get - 发送HTTP GET请求并获得响应,而无需将页面加载到浏览器;
  • splash:http_post - 发送HTTP POST请求并获得响应,而无需将页面加载到浏览器;

检查网络流量

示例

上面讲了这么这么多 API ,我们写一个简单的小例子吧:

function main(splash, args)
splash:set_viewport_size(400, 700)
assert(splash:go(args.url))
assert(splash:wait(0.5))
return {
url = splash:url(),
jpeg = splash:jpeg(),
har = splash:har(),
cookies = splash:get_cookies()
}
end

这里小编设置了当前浏览器页面的大小,返回了当前访问的 url ,并且将返回的图片格式改成了 jpeg ,同时返回了当前的 cookies 。

结果太长了,小编这里就不截图了,各位同学可以自己动手尝试下,属实很简单,并不难。

Splash HTTP API

上面我们介绍了如何在 Splash 主页上通过 Lua 脚本进行一些操作,但这并不是我们想要的,我们想要通过我们自己 Python 程序来结合 Splash 对页面进行抓取。

Splash 给我们提供了一些 HTTP API 接口,我们只需要请求这些接口并传递相应的参数即可,下面我们简单的介绍一下这些接口的使用。

更多内容可以查阅文档:https://splash.readthedocs.io/en/stable/api.html

render.html

此接口用于获取JavaScript渲染的页面的HTML代码,接口地址就是Splash的运行地址加此接口名称,例如 http://localhost:8050/render.html

比如我们使用某东做测试:

import requests

url = 'http://localhost:8050/render.html?url=https://www.jd.com'
response = requests.get(url)
print(response.text)

render.html 其实还支持很多参数,具体内容可以查阅文档获得。

render.png

此接口可以获取网页截图,其参数比 render.html 多了几个,通过width和height来控制宽高,它返回的是PNG格式的图片二进制数据,示例如下:

import requests

url = 'http://localhost:8050/render.png?url=https://www.jd.com&width=1000&height=700'
response = requests.get(url)
with open('jd.png', 'wb') as f:
f.write(response.content)

这里我们可以看到当前目录下多了一张名为 jd.png 的图片,如下:

render.har

此接口用于获取页面加载的HAR数据,示例如下:

import requests

url = 'http://localhost:8050/render.har?url=https://www.jd.com'
response = requests.get(url)
print(response.text)

结果太长了,小编就不贴了,结果是一个JSON格式的数据,其中包含页面加载过程中的 HAR 数据。

render.json

此接口包含了前面接口的所有功能,返回结果是JSON格式,示例如下:

url = 'http://localhost:8050/render.json?url=https://httpbin.org'
response = requests.get(url)
print(response.text)

结果如下:

{"url": "https://httpbin.org/get", "requestedUrl": "https://httpbin.org/get", "geometry": [0, 0, 1024, 768], "title": ""}

我们可以通过传入不同参数控制其返回结果。比如,传入 html=1 ,返回结果即会增加源代码数据;传入 png=1 ,返回结果即会增加页面PNG截图数据;传入 har=1 ,则会获得页面 HAR 数据。示例代码如下:

url = 'http://localhost:8050/render.json?url=https://httpbin.org/get&html=1&har=1'
response = requests.get(url)
print(response.text)

execute

此接口才最为强大的接口,我们前面用的那些 Lua 脚本,就是通过这个接口来与 Splash 进行对接的,我们将刚才上面的示例稍微改动下,代码如下:

import requests
from urllib.parse import quote lua = '''
function main(splash, args)
splash:go("https://www.geekdigging.com/")
return {
url = splash:url(),
jpeg = splash:jpeg(),
har = splash:har(),
cookies = splash:get_cookies()
}
end
''' url = 'http://localhost:8050/execute?lua_source=' + quote(lua)
response = requests.get(url)
print(response.text)

结果同样有点长,小编就不贴了。

本篇内容就到这里了,感谢观看。

示例代码

本系列的所有代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便大家取用。

示例代码-Github

示例代码-Gitee

参考

https://splash.readthedocs.io/en/stable/scripting-overview.html

https://splash.readthedocs.io/en/stable/api.html

https://github.com/scrapy-plugins/scrapy-splash

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

https://cuiqingcai.com/5638.html

小白学 Python 爬虫(39): JavaScript 渲染服务 scrapy-splash 入门的更多相关文章

  1. 小白学 Python 爬虫(40):爬虫框架 Scrapy 入门基础(七)对接 Selenium 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  2. 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  3. 小白学 Python 爬虫(42):春节去哪里玩(系列终篇)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  4. 小白学 Python 爬虫(28):自动化测试框架 Selenium 从入门到放弃(下)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  5. 小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  6. 小白学 Python 爬虫(7):HTTP 基础

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  7. 小白学 Python 爬虫(9):爬虫基础

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  8. 小白学 Python 爬虫(27):自动化测试框架 Selenium 从入门到放弃(上)

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  9. 小白学 Python 爬虫(2):前置准备(一)基本类库的安装

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 本篇内容较长,各位同学可以先收藏后再看~~ 在开始讲爬虫之前,还是先把环境搞搞好,工欲善其事必先利其器嘛~~~ 本篇 ...

随机推荐

  1. ThinkPHP5.1接收post、get参数

    我们要先认识的是请求对象Request类 <?php//要用Request类 第一步就要引入他,才能在当前控制器上使用//知识点:use 与 namespace前面不可有空格等其他操作.name ...

  2. Java反射机制(三):调用对象的私有属性和方法

    一. 通过反射调用类中的方法 在正常情况下,得到类的对象后,我们就可以直接调用类中的方法了,如果要想调用的话,则肯定必须清楚地知道要调用的方法是什么,之后通过Class类中的getMethod方法,可 ...

  3. hdu 2126 Buy the souvenirs(记录总方案数的01背包)

    Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  4. [转]Spring 注解大全与详解

    Spring使用的注解大全和解释 注解 解释 @Controller 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类 ...

  5. Python--day45--pymysql操作数据库详细

    1.一个pymysql往数据库提交数据的简单例子: import pymysql # user = "eric" # pwd = '123123' #增加 conn = pymys ...

  6. Python--day43--mysql唯一索引和外键变种之多对多

    唯一索引:(unique关键字)unique 名字 (num) 外键的变种:

  7. jekyll 添加 Valine 评论

    本文告诉大家如何在自己搭建的静态博客添加 Valine 评论.在这前,我基本都是使用 多说,但是多说gg啦,所以就在找一个可以替换的评论 本来 Disqus是很好的,但是在国内很难打开,所以我就需要一 ...

  8. 【u228】圣诞树

    [问题描述] 圣诞特别礼物挂在一棵圣诞树上,这棵树有n层,每层有一件礼物,每件礼物都有一个价值,有的礼物还有一些连结线,与下层的礼物相连,领取礼物的规则如下:任选一件礼物,它的下面如果有连结线,则可以 ...

  9. Linux 内核/sbin/hotplug 工具

    如同本章中前面提过的, 无论何时一个设备从系统中增删, 都产生一个"热插拔事件". 这 意味着内核调用用户空间程序 /sbin/hotplug. 这个程序典型地是一个非常小的 ba ...

  10. Linux 内核 EISA 总线

    扩展 ISA (EISA) 总线是一个对 ISA 的 32-位 扩展, 带有一个兼容的接口连接器; ISA 设备板可被插入一个 EISA 连接器. 增加的线在 ISA 接触之下被连接. 如同 PCI ...