python高阶爬虫实战分析


Posted in Python onJuly 29, 2018

关于这篇文章有几句话想说,首先给大家道歉,之前学的时候真的觉得下述的是比较厉害的东西,但是后来发现真的是基础中的基础,内容还不是很完全。再看一遍自己写的这篇文章,突然有种想自杀的冲动。emmm所以楼主决定本文全文抹掉重写一遍,并且为之前点进来看的七十多访问量的人,致以最诚挚的歉意。好想死。。

在学完了爬虫全部内容后,楼主觉得勉强有资格为接触爬虫的新人指指路了。那么废话不多说,以下正文:

一、获取内容

说爬虫一定要先说爬取内容的方法,python有这么几个支持爬虫的库,一个是urllib和它的后续版本库,这个库做爬取的时候生成的中继对象是比较多的,楼主也记不大住都有什么,而且这个库的使用在楼主看来有些过时了。更加建议做爬取的时候使用requests库(ps:不是request)

使用urllib:

html = urllib.request.urlopen(url).read()

使用requests:

r = requests.get(url)

对于获取到的内容,有以下方法进行处理:
1、使用正则表达式匹配。

2、使用BeautifulSoup对爬取内容标签对象化。

3、通过构造节点树使用Xpath获取元素。

第一种方法胜在直接,效率高而且不需要安装三方库。第二种方法胜在简单,标签对象化后不需要写复杂的正则表达式,而且提取标签更加方便。第三种方法胜在灵活,获取内容更加灵活,就是语法有点多,不熟的话可以对着Xpath语法文档写。

使用正则表达式匹配:

pattern_content = '<div class="rich_media_content " id="js_content">(.*?)</div>'
content1 = re.findall(pattern_content, html, re.S)

使用BeautifulSoup对爬取内容标签对象化:

soup = bs4.BeautifulSoup(html, 'lxml')
imgs = soup.find_all('img')

关于BeautifulSoup的安装请自行百度,没记错的话直接pip是可行的。

通过构造节点树使用Xpath获取元素:

selector=etree.HTML(html)
content=selector.xpath('//div[@id="content"]/ul[@id="ul"]/li/text()')

至此,爬取的基本内容就叙述完毕了,这里给出的是最简单的范例,如果想深入了解某种方法,建议去查询更详细的技术文档。

下面内容就是之前的了,略作删改。

二、伪造表单请求头

很多网站上的数据爬取比较简单,只需要直接request那个网址就可以,很多小型网站都是这样。面对这样的网站数据,只需要花个几分钟随便写几行代码,就能爬到我们想要的数据。

但是想要爬取稍微大型一些的网站数据,就不会这么容易了。这些网站的服务器,会分析收到的每一条request,来判断该请求是否为用户操作。这种技术,我们把它称为反爬技术。常见的反爬技术,楼主知道的有上面所述的分析请求,还有验证码技术。对于这两种情况,我们在构造爬虫程序的时候就需要稍微费点力气了。

先来介绍第一种的应对方法。首先我们要知道一条request的组成部分,不同网站的request格式可能会有点不同。对于这一点,我们可以通过浏览器的开发者工具,抓到一个网站的请求数据格式。如下图:

11111

此为使用谷歌浏览器抓取的请求信息。

我们可以看到request headers的格式,所以在访问这样的网站的时候,我们就不能忘了在postdata中放上一条伪造的headers。

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0',
			  'Referer': 'Address'}

其中referer键对应的值是要访问的网址。

某些网站还会需要有cookie的用户验证,我们可以通过调用

requests.Session().cookies

来获得它。

如果在爬虫中需要提交某些信息的话,还要构造一下postdata的数据。比如这样:

postData = {
		'username': ul[i][0],
		'password': ul[i][1],
		'lt': b.group(1),
		'execution': 'e1s1',
		'_eventId': 'submit',
		'submit': '%B5%C7%C2%BC',
	}

三、关于多网页的爬取

如果网页地址有规律,那么构造url用个循环函数就好,对于网页地址中包含随机码的时候,通常就是先爬取根页面,获取到所有想爬取的子页面url,把这些url放进一个url池(项目小是一维的列表,项目大的时候可能会是高维的列表)里,循环爬取。

而比较高效的方式是使用多线程技术,demo有点长只贴关键部分。

class Geturl(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
  def run(self):
    res = requests.get(url, headers=header)
    html = res.text
    # print(html)
    pattern_href = '<a target="_blank" href="(.*?)" rel="external nofollow" id'
    href = re.findall(pattern_href, html, re.S)
    for href in href:
      href = href.replace('amp;', '')
      a.put(href)
      a.task_done()
class Spider(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
  def run(self):
    href = a.get()
    res = requests.get(href, headers=header2)
    html = res.text
    pattern_title = '<title>(.*?)</title>'
    title = re.findall(pattern_title, html, re.S)
    pattern_content = '<div class="rich_media_content " id="js_content">(.*?)</div>'
    content1 = re.findall(pattern_content, html, re.S)
    print(title)
    # time.sleep(1.5)
    pattern_content2 = '>(.*?)<'
    content2 = re.findall(pattern_content2, content1[0], re.S)
    while '' in content2:
      content2.remove('')
    content = ''
    for i in content2:
      content = content + i
    content = content.replace(' ','')
    print(content)

开两个线程,一个爬取url放进url池,一个从url池里获取url然后爬取内容,再开一个线程监控两个线程,如果两个线程运行完毕,结束主线程。

python的多线程机制底层做的其实不好,理由不多讲。另,多线程具体操作很多就不展开讲了。

四、关于使用代理ip

很多网站会有ip检测机制,当同一ip以人力无法做到的速度多次访问网站时,通常就会触发这种机制。

代理ip的话,通常通过爬取一些开源ip网站发布的ip构建ip代理池,比如西刺、蘑菇等。这样的一些网站,直接百度代理ip就能找到。然后,使用Flask+Redis维护代理池。这部分详细说明也比较长,就不细说了。也不是爬虫必要的东西。另,自己有服务器的也可以使用SSR的翻墙工具,不过搭建不是楼主亲手做的,所以就不详细说明了。

五、关于selenium模仿浏览器操作

关于selenium主要介绍以下几点:

1、selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行处理(Selenium Grid)。

2、Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可以用于任何支持JavaScript的浏览器上。

3、selenium可以模拟真实浏览器,自动化测试工具,支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题。

4、用python写爬虫的时候,主要用的是selenium的Webdriver。

这些是某说明文档的内容,能看懂就看,看不懂就看楼主的简单版:

selenium的话主要用于模仿浏览器操作,比如向文本框中赋值,点击按钮等。配合高效率浏览器的话也是实现爬虫的一个比较好的方法。优点是通过模拟浏览器操作,不易被反爬检测。缺点是效率低下,非常不适合大型爬虫,小作坊自己玩玩就好。

六、关于Scrapy框架

这又是一块非常非常庞大的内容,很多技术一旦牵扯上框架就麻烦了。当然学会了的话,做大型项目就简单多了。重点就是框架一般针对比较大型的系统去做,所以其管理和操作会比较麻烦,内部的一些机制也不是很好说明。这一块的话如果以后有时间就单独写一篇文章详细介绍,毕竟从原理到搭建到配置到使用,内容太多。。

七、关于验证码处理

对于处理验证码的话,目前简单点的是直接使用PIL(pillow)做图像处理,然后使用Tesseract直接识别。此方法楼主已经写好了单独的文章供大家参考。

另,如果学过机器学习神经网络这部分的话,还可以使用卷积神经网络。这个方向楼主还正在学,简单给大家指条路,不详述。

以上是楼主想到的爬虫所有内容,若有错误还望指正。

Python 相关文章推荐
python中实现php的var_dump函数功能
Jan 21 Python
python实现指定字符串补全空格的方法
Apr 30 Python
在Python中的Django框架中进行字符串翻译
Jul 27 Python
Python读取一个目录下所有目录和文件的方法
Jul 15 Python
Scrapy基于selenium结合爬取淘宝的实例讲解
Jun 13 Python
python删除文件夹下相同文件和无法打开的图片
Jul 16 Python
Python列表切片常用操作实例解析
Dec 16 Python
pycharm通过anaconda安装pyqt5的教程
Mar 24 Python
浅谈tensorflow使用张量时的一些注意点tf.concat,tf.reshape,tf.stack
Jun 23 Python
python缩进长度是否统一
Aug 02 Python
Python列表嵌套常见坑点及解决方案
Sep 30 Python
Python图像识别+KNN求解数独的实现
Nov 13 Python
python3.5基于TCP实现文件传输
Mar 20 #Python
python3基于TCP实现CS架构文件传输
Jul 28 #Python
python cs架构实现简单文件传输
Mar 20 #Python
Tornado Web Server框架编写简易Python服务器
Jul 28 #Python
python使用tornado实现登录和登出
Jul 28 #Python
基于python实现简单日历
Jul 28 #Python
python使用tcp实现局域网内文件传输
Mar 20 #Python
You might like
PHP 中的类
2006/10/09 PHP
深入理解require与require_once与include以及include_once的区别
2013/06/05 PHP
php广告加载类用法实例
2014/09/23 PHP
Yii2主题(Theme)用法详解
2016/07/23 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
2017/07/19 PHP
PHP实现数组向任意位置插入,删除,替换数据操作示例
2019/04/05 PHP
使用PHP开发留言板功能
2019/11/19 PHP
javascript 多种搜索引擎集成的页面实现代码
2010/01/02 Javascript
善用事件代理,警惕闭包的性能陷阱。
2011/01/20 Javascript
编写可维护面向对象的JavaScript代码[翻译]
2011/02/12 Javascript
js获取系统的根路径实现介绍
2013/09/08 Javascript
js判断鼠标左、中、右键哪个被点击的方法
2015/01/27 Javascript
Javascript中实现String.startsWith和endsWith方法
2015/06/10 Javascript
vue从使用到源码实现教程详解
2016/09/19 Javascript
jquery中用函数来设置css样式
2016/12/22 Javascript
基于JavaScript实现活动倒计时效果
2017/04/20 Javascript
vue单页缓存方案分析及实现
2018/09/25 Javascript
聊聊Vue 中 title 的动态修改问题
2019/06/11 Javascript
layer弹出层扩展主题的方法
2019/09/11 Javascript
layui表单提交到后台自动封装到实体类的方法
2019/09/12 Javascript
vue输入节流,避免实时请求接口的实例代码
2019/10/30 Javascript
vscode自定义vue模板的实现
2021/01/27 Vue.js
[59:08]Ti4 冒泡赛第二天 NEWBEE vs Titan 2
2014/07/15 DOTA
Python实现扫描局域网活动ip(扫描在线电脑)
2015/04/28 Python
Python运维之获取系统CPU信息的实现方法
2018/06/11 Python
python如何从文件读取数据及解析
2019/09/19 Python
Python实现把多维数组展开成DataFrame
2019/11/30 Python
Python如何操作office实现自动化及win32com.client的运用
2020/04/01 Python
python 读取二进制 显示图片案例
2020/04/24 Python
Python tkinter实现日期选择器
2021/02/22 Python
Converse匡威法国官网:美国著名帆布鞋品牌
2018/12/05 全球购物
护士节活动总结
2014/08/29 职场文书
爱心募捐通知范文
2015/04/27 职场文书
入党转正介绍人意见
2015/06/03 职场文书
2015教师个人德育工作总结
2015/07/22 职场文书
Python中super().__init__()测试以及理解
2021/12/06 Python