少年们,你们双十一剁手了吗?现在收到快递了吗?现在是不是痛苦万分,天天过着吃土的日子啊?
吃土不要紧,只要有本事,就轮不到吃土。铲屎官今天就给大家带来一个骚气的爬虫操作,可以让你查询自己的快递状态。
这个就是 Splash 和 scrapy-splash。Splash是一个javascript渲染服务。它是一个带有HTTP API的轻量级Web浏览器,使用Twisted和QT5在Python 3中实现。所以,如果使用 Splash 的话,需要一台服务器做支撑。而 scrapy-splash 则是一个Python库,能够在 Scrapy 框架里面使用 Splash 。
今天,铲屎官就来拿这两个东西,来个你们捯饬捯饬如何能够优雅的查询到你的快递订单情况。
Splash初探
Splash在前面说了,是一个 JavaScript 渲染服务,所以,我们如果要玩 Splash,就需要一台机器作为服务器来支撑。哪里有服务器呢?你可以有两个选择:
- 使用自己的机器作为服务器来运行
- 用你双十一购买的阿里云服务器或者腾讯云服务器来做操作(推荐)
插播一则小福利:
虽然已经过了双十一了,但是,如果你还没有云服务器的话,可以通过下面的两个链接来领取价值千元的云服务器优惠券,原价300多的服务器,一年用了优惠券只要100多,不到200。超级实惠,数量有限,机会不多,大家要抓紧。
阿里云(最高¥1888云产品通用代金券):
https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=nrkmbo9q
腾讯云(总价值高达2775元代金券):
https://cloud.tencent.com/redirect.PHP?redirect=1025&cps_key=b351b2fc50b15866ff9d19b58a5df0f5
铲屎官这里,就给大家演示在阿里云服务器上面是怎么操作的。因为双十一的时候,阿里云的服务器那是真的便宜啊。如果你那个时候还在犹豫,没有买,那么对不起,你的犹豫耽误了你上车,现在的服务器如果领券了也要将近200一年。所以,在机遇面前,人要当机立断,千万不能犹豫。如果你没有服务器,那么本地安装步骤也基本一致。如果有什么细微不一样的地方,安装过程请简单百度一下,网络一堆答案。
进群:548377875 即可获取小编精心准备的资料哦!
如果要装Splash,我们首先需要在 Linux服务器上面安装 Docker。
大家别慌,别听到 Docker 就觉得这个东西好高大上,好神秘。其实,我们这里使用 Docker 就是为了两点:一是安装 Splash;二是运行 Splash 服务。
我拿来讲解的阿里云服务器上面安装的是 CentOS 7.4 系统。
首先,通过命令 $ docker --version 来检测你的服务器上之前有没有安装过 Docker。
如果没有安装过,那么 Docker 要求 CentOS 系统的内核版本高于 3.10 ,所以前提条件来验证你的CentOS 版本是否支持 Docker 。输入以下命令即可查看:
1$ uname -r
我的服务器出现的结果如下:
显示的结果是大于3.10,可以安装。
接着,我们需要升级一下 yum 和开始安装,这个简单,依次输入下面的命令就可以:
1# 升级 yum 2$ yum update 3 4# 安装需要的软件包依赖 5$ yum install -y yum-utils device-mapper-persistent-data lvm2 6 7# 设置yum源 8$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 9 10# 安装docker(由于repo中默认只开启stable仓库,故这里安装的是最新稳定版) 11$ yum install docker-ce 12 13# 启动并加入开机启动 14$ systemctl start docker 15$ systemctl enable docker
如果一切运行完毕,那么就说明 Docker 安装成功并且已经运行起来了,通过命令 $ docker version 来查看是否成功:
有client和service两部分表示docker安装启动都成功了。
接下来,我们来安装 Splash 。安装炒鸡简单,就只需要输入以下命令就可以:
1$ docker pull scrapinghub/splash
这个安装过程时间有点长,在这期间,可以去阿里云或者腾讯云的云服务器控制台,去吧相关安全组接口打开。
安装完成之后,长这个样子:
由于 Splash 启动端口默认是 8050,所以我们得需要在安全组里面,打开这个端口才可以。
如果你是阿里云,请参考一下操作步骤:
如果你是腾讯云,请参考一下操作步骤:
接着,我们通过命令来在你的服务器上启动 Splash。
1$ docker run -p 8050:8050 scrapinghub/splash
这个时候,Splash服务就成功启动了。如果想查看Splash服务启动是否成功,只需要在你的浏览器里面去访问你服务器的8050端口就可以。浏览器里面输入 http://<你服务器的公网IP地址>:8050/,如果是本地运行,则输入http://localhost:8050/。这个地址可以打开,页面长这个样子:
如果这个页面出现,那么就代表 Splash 服务成功启动。这个页面的作用,其实你可以在一定程度上面起到调试的作用。注意右边,有一个白色的输入框,还有一个大的黑色的输入框。白色的输入框是用来输入网页地址的;而黑色的框则是用LUA语言来编写Splash脚本的。为什么会有些脚本语言的地方?因为 Splash 是一个 JavaScript 的渲染服务,在这其中,你可能需要模拟一些用户的行为,但是模拟行为就是通过代码来实现的,所以需要写一些代码。
我们可以先来尝试的玩一下,在白色输入地址的框框里面,输入百度的地址:https://www.baidu.com/ ,然后点击 Redner me!:
这个页面是不是很酷炫?这里主要有三个成分:最上面是页面渲染之后的图片,中间是HAR信息,最下面则是页面渲染之后的html信息。接着我们看一下 Script 里面有什么东西:
这里面相当简单,相当于 Hello World。我在这里给大家简单讲解一下:
首先是有一个 Main 函数,这个就是 Splash 的入口函数,里面有两个参数,一个是splash,另一个是 args。
接着是 splash:go() 方法,参数是一个url,这个方法的目的就是指定服务跳转到这个url。
然后是 splash:wait() 方法,是让页面等待xx秒。因为有些渲染需要时间,所以这里要等待。
最后就是返回方法,我们看到返回三部分,分别对应的是 image, har 和 html。
结构非常清晰,如果有想更多了解其他方法的同学,可以参考这个链接里面的内容,方法写的非常详细:
https://cuiqingcai.com/5638.html
Scrapy-splash爬虫查询快递
这里主要讲解 Scrapy-splash 的使用,如果对 Scrapy 爬虫框架不是很了解的话,可以阅读下面这篇铲屎官的文章,做一下了解:
PeekpaHub全栈开发教程【节选内容】
首先,我们得在本地的机器上面安装 scrapy-splash:
1$ pip install scrapy-splash
接着,我们需要创建一个 Scrapy 工程,这里,我们需要在 settings.py 文件里面修改一些东西,我们需要把 Splash 服务器的接口配置上去,同事还需要添加splash的中间层。
1SPLASH_URL = 'http://<你Splash服务器的IP地址,如果是本地的,则是localhost>:8050' 2 3SPIDER_MIDDLEWARES = { 4 'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,5} 6 7DOWNLOADER_MIDDLEWARES = { 8 'scrapy_splash.SplashCookiesMiddleware': 723,9 'scrapy_splash.SplashMiddleware': 725,10 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810 11}
接着,我们需要修改我们的爬虫文件。我们这里是需要爬去百度页面的快递信息,比如,我的订单号是“71421570320700”,然后在百度里面一输入这个号码,会自显示出来订单号信息:
信息就是这样,我们可以通过 Chrome 浏览器的开发者工具,来看一下网页源码里面,快递信息对应的地方结构是什么:
看到这个是一个 div 标签,它里面的特征是 class="op_express_delivery_timeline_info",所以,我们的爬虫写成这样:
1import scrapy 2from bs4 import BeautifulSoup 3from scrapy_splash import SplashRequest 4 5script = """ 6 function main(splash,args) 7 assert(splash:go(args.url)) 8 assert(splash:wait(args.wait)) 9 js = string.format("document.querySelector('#kw').value=%s;document.querySelector('#su').click()",args.cargoNo) 10 splash:evaljs(js) 11 assert(splash:wait(args.wait)) 12 return splash:html() 13 end 14 """ 15 16class JavspiderSpider(scrapy.Spider): 17 name = 'JavSpider' 18 allowed_domains = ['javpop.com'] 19 20 # start request 21 def start_requests(self): 22 urlBaidu = "https://www.baidu.com/" 23 yield SplashRequest(urlBaidu,callback=self.parse_page,endpoint='execute',24 args={'lua_source': script,'cargoNo': '71421570320700','wait': 1}) 25 26 # parse the html content 27 def parse_page(self,response): 28 content = response.body 29 soup = BeautifulSoup(content,"html.parser") 30 div_list = soup.find_all('div',attrs={"class": "op_express_delivery_timeline_info"}) 31 print('=' * 40) 32 for item in div_list: 33 print(item.text) 34 print('=' * 40)
这里的爬虫写的很简单,只是为了给大家展示一下 Scrapy-splash 的使用。简单的说一下爬虫的结构:
首先是有 script 变量,这个变量就是我们在之前提到的黑色框框里面的Lua脚本。这里的代码逻辑就是,先去百度页面,然后在搜索框里面输入订单号,然后点击搜索按钮。
然后在 start_request() 方法里面,我们调用的是 SplashRequest() 方法。我们需要调的是scrapy-splash的 SplashRequest,而不是之前的 scrapy 的 Request。
最后就是 args 里面,我们传入的参数有这么几个,这几个参数对应的就是 script 里面的变量。
其他都是标准的爬虫流程,比如用 BeautifulSoup 来解析 html 等。
如果这个时候爬虫运行,则可以看到控制台输出了结果:
我们看到,这个快递信息已经答应出来了。我们的教学任务就此完成。
后续
这个可以再扩展一下,比如把快递信息封装起来啊,存储起来啊,玩法有很多,大家可以自行发挥。