爬虫与反爬虫

反爬虫爬取豆瓣书单

Posted by Min on November 14, 2018

前言

尝试解决一种设置了反爬取的网站的应对措施,或以获取较高价值的资料为目的,使用各种库,包括自动使用和更换多个proxy进行高效率爬取的库,自行编写程序予以实现;(适合于已经有较好编程能力的同学) 总体思路如下:

  1. 找一个有反爬虫的网站(豆瓣),并进行最基本的爬取测试
  2. 查找该网站的反爬虫机制,并查找相关解决方案
  3. 对相关反爬虫机制进行破解,对代码进行反爬虫扩展
  4. 爬取网站,并对爬虫代码进行改进

正文

反爬虫的几种常用方法: 如题,我们通过查询相关资料,可以知道几种比较常用的反爬虫方法。 1、爬取过程中的302重定向 我们在爬取某个网站速度过快,时间间隔完全一样或者发出的请求过多的时候,网站会向你发送一个链接,主要是验证码,来认证是否是用户在使用。一般可以通过设置随机访问时间解决。 对于302重定向的问题,是由于抓取速度过快引起网络流量异常,服务器识别出是机器发送的请求,于是将请求返回链接定到某一特定链接,大多是验证图片或空链接。在这种时候,既然已经被识别出来了,就使用代理ip再继续抓取。 time.sleep(random.randint(0,3)) # 暂停0~3秒的整数秒,时间区间:[0,3] 2、headers头文件 有些网站禁止爬取,在robots.txt里对爬虫请求一律拒绝,这时候我们需要伪装成浏览器,通过修改http中的headers来实现。如常用的火狐浏览器和chrome浏览器。 headers = { ‘Host’: “www.douban.com”, ‘Accept’: “text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8”, ‘Accept-Encoding’: “gzip, deflate, sdch”, ‘Accept-Language’: “zh-CN,zh;q=0.8”, ‘User-Agent’: “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36”, ‘Connection’: “keep-alive”, } p = requests.get(url, headers=headers) print(p.content.decode(‘utf-8’)) 3、模拟登陆 一般常用网站的登录都需要有验证码,这里我们可以使用selenium构造post数据进行提交,将返回验证码图片的链接地址输出到控制台下,点击图片链接识别验证码,输入验证码并提交,完成登录。 我一般会使用PhantomJS,phantomjs是一个无界面的浏览器,非常适合爬取各种难以爬取的网站。模拟浏览器行为进行操作。当我们遇到JS渲染的网页,在使用正则表达式、BS4和xpath都无法匹配出数据时(数据根本没加载上),可以使用PhantomJS模拟浏览器行为发送请求,将会得到网页的原始全部数据。(phantomjs是浏览器,爬取速度有限,最近selenium不再支持phantomjs了) 4、代理ip 当爬取速度过快时,当请求次数过多时都面临ip被封的可能。因此使用代理也是必备的。豆瓣就是当爬取到一定量的界面时,就会封掉当前IP,最简单高效的方法就是使用代理IP。网上虽然有很多号称免费的代理网站,但很多都是无效的IP,基本上10个里面差不多才有一个能用的,所以需要进行测试,使用可用的代理IP。这就要去不仅要爬取可用的IP,还需要对IP进行测试,并将可用的IP写入json中。后面会有详细描述。 5、验证码输入 验证码处理问题,一般常用网站的验证码对于现在的算法来讲还是很难识别的,比较验证码就是为了区别人与机器的,我一般都是人工识别:获取验证码的链接再控制台下 ——> 点击链接识别验证码 ——> 在控制台手动输入验证码并提交。当然也有一些比较好的云端识别验证码的网站,不过好像要收费,或者需要TensorFlow训练。 6、ajax加载的数据 对于ajax加载的数据,一般我们无论通过request或post方法请求得到的网页都无法得到。 关于一个网页是否是ajax加载数据,我们只需将网页内容print到控制台下,将其与网页原始内容进行比对,如果有数据缺失,那么这些数据就是ajax加载。例如:我们想获取京东上商品的价格、销量、好评等方面的数据,但是请求返回的网页中没有这些数据。因为这些数据是ajax加载。对于ajax加载的页面,一般有两种方法。 (1)分析网页 按F12打开浏览器调试工具,在Network下选择XHR或Doc标签,分析(双击点开查看)这两个标签下的链接。如果点开链接打开的网页中正好有那些没有加载的数据,则这些数据是通过该链接传送的。再对该链接进行规律分析,以后对该链接发送请求。一般大型的网站链接都是有规律的,但是一些小型的网站往往没什么规律。 (2)使用PhantomJS模拟浏览器行为 使用PhantomJS模拟浏览器进行发送请求,得到返回的内容是完全的(ajax加载的数据也会有)。但是使用PhantomJS请求速度过慢,一般一个网页1~3s时间。对于速度有要求的爬虫,一般要使用PhantomJS需要开多线程。 from selenium import webdriver driver = webdriver.PhantomJS(executable_path=’D:anaconda3\phantomjs.exe’) # 构造网页驱动 driver.get(‘https://www.douban.com/’) print(driver.page_source) # 打印网页内容

7、phantomJS是一个很有用的工具 一般对于一个比较复杂的网站,如果它还拥有很多反爬虫机制,我个人觉得可以直接使用phantomJS,phantomJS可以帮助你简单高效的爬取99%的网页。当然它爬取的速度相对于scrapy来讲可能有点慢,但是它的速度对于大多数人来讲都是可以接受的。尤其是在爬取动态网页时,将会大大减少你所使用的时间。 比如爬取豆瓣(大部分网站),只需要下面几行代码: from selenium import webdriver driver = webdriver.PhantomJS(executable_path=’D:anaconda3\phantomjs.exe’) # 构造网页驱动 driver.get(‘https://www.douban.com/’) print(driver.page_source) # 打印网页内容

##结论 PhantomJS 真香!!!