1、作爬虫所须要的基础前端
要作一只爬虫,首先就得知道他会干些什么,是怎样工做的。因此得有一些关于HTML的前置知识,这一点作过网页的应该最清楚了。python
HTML(超文本标记语言),是一种标记性语言,自己就是一长串字符串,利用各类相似 < a >,< /a>这样的标签来识别内容,而后经过浏览器的实现标准来翻译成精彩的页面。固然,一个好看的网页并不只仅只有HTML,毕竟字符串是静态的,只能实现静态效果,要做出漂亮的网页还须要能美化样式的CSS和实现动态效果的JavaScipt,只要是浏览器都是支持这些玩意儿的。web
嗯,咱们作爬虫不须要了解太多,只须要了解HTML是基于文档对象模型(DOM)的,以树的结构,存储各类标记,就像这样:正则表达式
以后会用到这种思想来在一大堆HTML字符串中找出咱们想要的东西。数据库
了解了这个而后还得了解网页和服务器之间是怎么通讯的,这就得稍微了解点HTTP协议,基于TCP/IP的应用层协议,规定了浏览器和服务器之间的通讯规则,简单粗暴的介绍几点和爬虫相关的就是:浏览器
浏览器和服务器之间有以下几种通讯方式:安全
GET:向服务器请求资源,请求以明文的方式传输,通常就在URL上能看到请求的参数服务器
POST:从网页上提交表单,以报文的形式传输,请求资源cookie
还有几种比较少见就不介绍了。网络
了解了这两点就能够准备工具了,固然,对爬虫有兴趣还能够了解一下爬虫的发展史。
2、介绍几款优秀制做爬虫的辅助工具
因为我是采用python3.6开发的,而后从上文的介绍中,也该知道了一只爬虫是须要从HTML中提取内容,以及须要和网页作交互等。
若是不采用爬虫框架的话,我建议采用:
BeautifulSoup 库 ,一款优秀的HTML/XML解析库,采用来作爬虫,
不用考虑编码,还有中日韩文的文档,其社区活跃度之高,可见一斑。
[注] 这个在解析的时候须要一个解析器,在文档中能够看到,推荐lxml
Requests 库,一款比较好用的HTTP库,固然python自带有urllib以及urllib2等库,
但用起来是绝对没有这款舒服的,哈哈
Fiddler. 工具,这是一个HTTP抓包软件,可以截获全部的HTTP通信。
若是爬虫运行不了,能够从这里寻找答案,官方连接可能进不去,能够直接百度下载
爬虫的辅助开发工具还有不少,好比Postman等,这里只用到了这三个,相信有了这些能减小很多开发阻碍。
3、最简单的爬虫试例
最简单的爬虫莫过于单线程的静态页面了,这甚至都不能叫爬虫,单单一句正则表达式便可匹配出全部内容,好比各类榜单:豆瓣电影排行榜,这类网站爬取规则变化比较少,用浏览器自带的F12的审查很容易找到须要爬取信息的特征:
见到花花绿绿的HTML代码不要惧怕,一个一个点,直到找到须要的信息就好了,能够看到全部电影名都是在这样
之下的,每有一个这样的标签就表明一个电影,从他的孩子< span >中便可抓取到电影名。
代码以下:
抓取结果以下:
乍一看,就这么个玩意儿,这些电影名还不如直接本身去网页看,这有什么用呢?可是,你想一想,只要你掌握了这种方法,若是有翻页你能够按照规则爬完了一页就解析另一页HTML(一般翻页的时候URL会规律变化,也就是GET请求实现的翻页),也就是说,只要掌握的爬取方法,不管工做量有多么大均可以按你的心思去收集想要的数据了。
4、须要模拟登陆后再爬取的爬虫所须要的信息
4.1.登陆分析
刚才的爬虫未免太简单,通常也不会涉及到反爬虫方面,这一次分析须要登陆的页面信息的爬取,按照往例,首先打开一个网页:
我选择了我学校信息服务的网站,登陆地方的代码以下:
能够看到验证码都没有,就只有帐号密码以及提交。光靠猜的固然是不行的,通常输入密码的地方都是POST请求。
POST请求的响应流程就是 客户在网页上填上服务器准备好的表单而且提交,而后服务器处理表单作出回应。通常就是用户填写账号、密码、验证码而后把这份表单提交给服务器,服务器从数据库进行验证,而后做出不一样的反应。在这份POST表单中可能还有一些不须要用户填写的用脚本生成的隐藏属性做为反爬虫的手段。
要知道表单格式能够先试着随便登陆一次,而后在F12中的network中查看登陆结果,如图:
【注】若是用真正的帐号密码登陆,要记住勾选上面的Preserve log,这样即便网页发生了跳转以前的信息也还在。
从上面的两张图中很容易发现其中的一个POST请求, login?serv…就是登陆请求了
能够看到这个登陆请求所携带的信息有:
General: 记录了请求方式,请求地址,以及服务器返回的状态号 200等
Response Headers: 响应头,HTTP响应后传输的头部消息
Request Headers: 请求头,重点!!,向服务器发送请求时,发出的头部消息,之中不少参数都是爬虫须要模拟出来传送给服务器的。
From Data:表单,重点!!,在这里表单中有:
username: 12345
password: MTIzNDU=
lt: e1s1
_eventId: submit
我明明都填的12345,为何密码变了呢?能够看出这密码不是原始值,应该是编码后的产物,网站经常使用的几种编码/加密方法就几种,这里是采用的base64编码,若是对密码编码的方式没有头绪能够仔细看看登陆先后页面的前端脚本。运气好能够看到encode函数什么的。
若是你不想错过Python这么好的工具,又担忧自学遇到问题无处解决,如今就能够Python的学习q u n 587-137-371能够来了解一块儿进步一块儿学习!免费分享视频资料
4.2信息提取
若是了解过Resquests库的文档就知道,发送一个通常的POST请求所须要的参数构造是这样的:
从上面的两张图片中便可找到发送一个正确的请求所须要的参数,即 url 和 data :
url 即上面的 Request URL:
Request URL: http://uia.hnist.cn/sso/login?service=http%3A%2F%2Fportal.hnist.cn%2Fuser%2FsimpleSSOLogin
data 即上面的From data:
收集到了必要的信息还得了解三点:
1、登陆后的网页和服务器创建了联系,因此能和服务器进行通讯,但即便你从这个网页点击里面的超连接跳转到另一个子网页,在新网页中仍是保持登陆状态的在不断的跳转中是怎么识别用户的呢?
在这里,服务器端通常是采用的Cookie技术,登录后给你一个Cookie,之后你发出跳转网页的请求就携带该Cookie,服务器就能知道是你在哪以什么状态点击的该页面,也就解决了HTTP传输的无状态问题。
很明显,在模拟登陆之后保持登陆状态须要用得着这个Cookie,固然Cookie在请求头中是可见的,为了本身的帐号安全,请不要轻易暴露/泄漏本身的Cookie
2、先了解一下,用python程序访问网页的请求头的User-Agent是什么样的呢?没错,以下图所示,很容易分辨这是程序的访问,也就是服务器知道这个请求是爬虫访问的结果,若是服务器作了反爬虫措施程序就会访问失败,因此须要程序模拟浏览器头,让对方服务器认为你是使用某种浏览器去访问他们的。
3、查找表单隐藏参数的获取方式,在上文表单列表中有个lt参数,虽然我也不知道他是干吗的,但经过POST传输过去的表单确定是会通过服务器验证的,因此须要弄到这份参数,而这份参数通常都会在HTML页面中由JS脚本自动生成,能够由Beautifulsoup自动解析抓取。
关于Fiddler的使用和请求信息相关信息能够查看连接:https://zhuanlan.zhihu.com/p/21530833?refer=xmucpp
嗯,最重要的几样东西已经收集完毕,对Cookie和请求头的做用也有了个大概的了解,而后开始发送请求试试吧~
5、开始编码爬虫
若是用urllib库发送请求,则须要本身编码Cookie这一块(虽然也只要几行代码),但用Requests库就不须要这样,在目前最新版本中,requests.Session提供了本身管理Cookie的持久性以及一系列配置,能够省事很多。
先以面对过程的方式实验地去编码:
[注] 若是使用了Fiddler,他会自动为Web的访问设置一个代理,这时候若是你关闭了Fiddler可能爬虫会没法正常工做,这时候你选择浏览器直连,或者设置爬虫的代理为Fiddler便可。
[注2]爬虫不要频率太快,不要影响到别人服务器的正常运行,若是不当心IP被封了可使用代理(重要数据不要使用不安全的代理),网上有不少收费/免费的代理,能够去试下。
过程当中得到的经验:
在上面第一部分,不知道做用的参数不要乱填,只须要填几个最重要的就够了,好比UA,有时候填了不应填的请求将会返回错误状态.,尽可能把可分离的逻辑写成函数来调用,好比生成的表单参数,加密方法等.
在上面第二部分若是请求失败能够配合抓包软件查看程序和浏览器发送的请求有什么差异,遗漏了什么重要的地方,尽可能让程序模仿浏览器的必要的行为。
第三部分中,由于拿到的数据是以下图1这样的,因此须要最后输出后decode,而后再使用正则表达式提取出双引号中的内容链接诶成一个标记语言的形式,再使用Beautifulsoup解析得到须要的数据,如图2.
中途可能利用的工具备:
官方正则表达式学习网站
HTML格式美化
正则表达式测试
6、爬虫技术的拓展与提升
经历了困难重重,终于获得了想要的数据,对于异步请求,使用JS渲染页面后才展现数据的网页,又或是使用JS代码加密过的网页,若是花时间去分析JS代码来解密,简单的公有的加密方法却是无所谓,但对于特别难的加密就有点费时费力了,在要保持抓取效率的状况下可使用能使用Splash框架:
这是一个Javascript渲染服务,它是一个实现了HTTP API的轻量级浏览器,Splash是用Python实现的,同时使用Twisted和QT。Twisted(QT)用来让服务具备异步处理能力,以发挥webkit的并发能力。
就好比像上面返回成绩地址的表单参数,格式为text,而且无规律,有大几十行,若是要弄明白每一个参数是什么意思,还不如加载浏览器的JS 或 使用浏览器自动化测试软件来获取HTML了,因此,遇到这种状况,在那么大一段字符串中,只能去猜哪些参数是必要的,哪些参数是没必要要的,好比上面的,我就看出两个是有关于返回页面结果的,其他的有可能存在验证身份的,时间的什么的。
对于信息的获取源,若是另外的网站也有一样的数据而且抓取难度更低,那么换个网站爬多是个更好的办法,以及有的网站根据请求头中的UA会产生不一样的布局和处理,好比用手机的UA可能爬取会更加简单。
7、后记
几天后我发现了另外一个格式较好的页面,因而去爬那个网站,结果他是.jsp的,采用以前的方法跳转几个302以后就没有后续了…后来才猜测了解到,最后一个302多是由JS脚本跳转的,而我没有执行JS脚本的环境,也不清楚他执行的哪一个脚本,传入了什么参数,因而各类尝试和对比,最后发现:正常请求时,每次都多2个Cookie,开始我想,Cookie不是由Session管理不用去插手的吗?而后我想以正常方式得到该Cookie,请求了N个地址,结果始终得不到想要的Cookie,因而我直接使用Session.cookies.set('COMPANY_ID','10122')添加了两个Cookie,还真成了…神奇…
固然,过了一段时间后,又不行了,因而仔细观察,发现每次就JSESSIONID这一个Cookie对结果有影响,传递不一样的值到不一样的页面还…虽然我不认同这种猜的,毫无逻辑效率的瞎试。但经历长时间的测试和猜想,对结果进行总结和整理也是能发现其中规律的。
关于判断某动做是否是JS,能够在Internet选项中设置禁止使用JS
关于失败了验证的方法,我强烈建议下载fiddler,利用新建视图,把登陆过程当中全部的图片,CSS等文件去掉之后放到新视图中,而后利用程序登陆的过程也放一个视图当中,若是没有在响应中找到须要的Cookie,还能够在视图中方便的查看各个JS文件,比浏览器自带的F12好用太多了。 以下图:
总之,通过这段时间的尝试,我对爬虫也有了个初步的了解,在这方面,也有了本身作法:
抓包请求 —> 模仿请求头和表单—>若是请求失败,则仔细对比正常访问和程序访问的数据包 —>成功则根据内容结构进行解析—>清清洗数据并展现
本文来源于网络 若有侵权请联系做者删除