关于什么是网络爬虫我就不在这里详细介绍了,如果你不知道,那可能后面的文字你可能看不懂。
我是2018年7月份开始自学Python然后做网络爬虫的,到今天2019年11月17日,一年多点的经验。在这里我想谈点我的经验,抛砖引玉。
在搜索引擎上搜网络爬虫,出来的绝大多数都是Python培训相关的广告。搞网络爬虫,基本上大家都首选Python编程语言。我想原因无非就是Python更简单易学,代码量更小。如果你完全没有编程基础,想学习编程,选择学习Python可能更适合,因为它最简单,更接近于英语的自然表达。如果Python都学不会,那么其它的Java之类的就更不可能学会了。如果你不想专业从事IT职业,只想学习了解一下,或者只想学点代码解决工作中遇到的问题,那么Python也很适合,Python有大量的开源库可以利用,比如说Pandas用来处理Excel数据等。总之,开发网络爬虫其实用很多语言都可以实现,用Java可以,JavaScript(Node.js)可以,Go也可以,甚至是被调侃为世界上最好的言语的PHP都可以,但基本上都没有Python更简单。
这段时间从新闻上看到房地产大老板潘石屹都在学习Python,人家超级富豪而且五十多的人了都在学习,说明Python入门简单而且这门编程语言很有用,越是有钱的人越更爱学习越努力。我去年因为工作需要开始自学Python,把Python当做我的第二开发语言,感觉还好。
言归正传。搞网络爬虫开发,首先得了解网络爬虫的技术原理。其实网络爬虫的技术原理很简单,无非就是http或https协议,通过代码发GET或POST请求,得到网页代码,然后解析HTML、JavaScript或其它资源,然后解析获取到想要的数据,然后保存,就这么回事。了解了原理,那么你用什么编程语言就不重要了。网络爬虫开发的难点主要是突破各种反爬虫的技术,比如说验证码、封杀IP、Cookie识别、网络字体、JavaScript渲染等。
以下是我常用的Python库或软件:
Request、Scrapy、lxml、selenium、Redis、Mongodb
我用的Python版本是3.7
Request库:简单的爬虫,用Request + lxml就够了,Request 用来发送HTTP请求,lxml用来解析HTML以便提取数据。
Scrapy:如果爬虫规模较大,强调抓取速度,就可能需要Scrapy了。当然你自己写异步方法也可以加快抓取速度,但不如直接用Scrapy方便。
Selenium:如果你要抓取的网页是大量使用了JavaScript前端渲染的页面,则可能需要Selenium了。Selenium操控chrome浏览器,无头浏览器的模式在服务器上也是可以的。少量使用了JavaScript的网页,用PyExecJS也可以搞定,不需要上Selenium。
Redis:Redis主要是用于网址去重。Redis可以结合Scrapy做分布式爬取。
MongoDB:MongoDB用于数据保存。我不建议用MySQL这类关系数据库,因为爬虫提取出来的数据比较乱,使用MySQL的话,一旦需要新增字段或删除字段,或者字段需要变更长度和类型,数据量大的情况下MySQL就比较麻烦了,而Mongodb则很灵活,所以强烈推荐MongoDB用来保存爬虫数据。
一般的小网站,基本上没什么反爬虫的手段,很容易就可以爬取。大型商业网站一般都有反爬虫措施,爬取难度就大大提高了。爬虫与反爬虫是矛与盾的关系,想要稳定的爬取到数据,就必须了解反爬虫技术,这样才能有针对的去突破网站的反爬虫技术。下面谈谈商业网站的反爬虫技术。一般来说,商业网站的反爬虫技术会有以下这些:
一、封锁IP
封锁IP是常见的反爬虫措施。网站检测到某个IP短时间请求了大量的网页,就封禁IP,这是最简单的办法。网站一般会使用Redis这类缓存,记录每个IP访问的网页,如果发现某个IP在一定的时间段内浏览的网页数量较大,则列入黑名单禁止访问,当然这个黑名单一般都是设置了有效期的,如果是长期的话黑名单就会越来越大。
突破IP封锁的办法有两种,要么就是降低爬虫的浏览速度,要么更换User-Agent,要么就是使用网络代理。
搞爬虫还是抓取速度建议不要太快,万一把人家服务器搞瘫痪,是要负法律责任的,有可能会坐牢。我建议请求网页都设置个时间延迟,不要给目标网站的服务器造成太大压力。
无论是浏览器还是爬虫程序,在向服务器发起网络请求的时候,都会发过去一个头文件:headers 这里面的大多数的字段都是浏览器向服务器”表明身份“用的,其中一个重要的字段就是User-Agent。一个局域网里面的很多电脑,IP地址都是一样的,网站如果只是简单的封锁IP,会导致误杀很多用户,所以网站可以采用IP + User-Agent结合的办法来封杀。爬虫对每个请求都随机更换User-Agent,甚至伪装成百度或搜狗的爬虫,也可以降低被反爬虫措施识别的概率。
关于爬虫的代理,我不建议使用自建代理IP池,用代理隧道更合适。
二、JavaScript渲染内容
普通的HTML网页提取就太简单了,会点XPath技术就可以搞定。但是如果网页上有JavaScript渲染内容,这时候怎么办呢?简单的可以用PyExecJS,复杂的就只能模拟浏览器了,用Selenium这类工具。
三、Cookie限制
用户第一次访问网页,网站就会设置个Cookie来识别用户,当网站识别到某个Cookie访问过频,就会封杀。
爬虫的解决办法可以用Redis这类内存数据库建立一个Cookie池,爬虫访问的时候随机更换cookie,这样而已可以降低被反爬虫措施识别的概率。
四、检测用户行为
网站可以利用JavaScript识别用户打开网页后是否有滚动,是否鼠标滑过某个区域等。
爬虫的解决办法也很简单,利用Selenium这类工具模拟浏览器访问,打开网页后做一些滚动这类操作,就可以绕过这类反爬虫手段。
五、验证码
验证码是最难解决的反爬虫手段。一般的文字验证码可以使用百度或阿里云的免费文字识别接口搞定,也可以使用TensorFlow这类工具来自己训练验证码识别模型搞定,如果是很复杂的验证码,估计就无能为力了。至于有些验证码需要滑动轨迹之类的,人眼观看都困难,这就更难了。
六、文字显示成图片
有些网站会把重要数据用图片显示,不是直接显示成文字。
解决办法也很简单,用图片文字识别工具搞定。百度、阿里云等都有图片文字识别接口。
七、CSS ::before 伪元素混淆
有些网站的反爬虫措施比较高明,利用CSS ::before 伪元素混淆,你在HTML里面提取到的是假数据,二它用CSS ::before 伪元素显示出来的才是真数据。
解决办法:
找它的CSS ::before 伪元素混淆规律,研究它的混淆是什么规则,就可以突破。
八、JavaScript混淆给假数据
这个跟CSS ::before 伪元素混淆很相似,通过JavaScript来混淆,你在HTML里面提取到的很可能是假数据。
解决办法:也是需要找到混淆的规律。
九、自定义网络字体
这个也是跟CSS ::before 伪元素混淆和JavaScript混淆很相似,自定义网络字体也是很有用的反爬虫办法。
解决办法:也是需要找自定义网络字体的规律。
爬虫与反爬虫的攻与防无非就是上面这些手段,详细的爬虫方法以后会继续展开介绍,敬请关注。最难搞定的是复杂的验证码。当然有复杂验证码的网站也不是完全没有办法,毕竟验证码太复杂,跳出验证码太频繁,这也会导致网站的用户体验太差,所以一般只要经常换IP、换User-Agent、换Cookie,速度降低一些,时间长一点还是能爬取到数据的。
在最后我想提醒的是,搞爬虫还是不要竭泽而渔,不要拼命的抓取影响人家网站的正常运作,不要去碰隐私数据,否则就违法了。