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的random模块及加权随机算法的python实现方法
Jan 04 Python
使用Python对Access读写操作
Mar 30 Python
python中返回矩阵的行列方法
Apr 04 Python
python中datetime模块中strftime/strptime函数的使用
Jul 03 Python
python使用zip将list转为json的方法
Dec 31 Python
python中sort和sorted排序的实例方法
Aug 26 Python
使用OpenCV实现仿射变换—旋转功能
Aug 29 Python
Python判断三段线能否构成三角形的代码
Apr 12 Python
Python工程师必考的6个经典面试题
Jun 28 Python
Django和Ueditor自定义存储上传文件的文件名
Feb 25 Python
Django项目如何正确配置日志(logging)
Apr 29 Python
Python实现socket库网络通信套接字
Jun 04 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分页示例代码
2007/03/19 PHP
用PHP即时捕捉PHP中的错误并发送email通知的实现代码
2013/01/19 PHP
php判断GIF图片是否为动画的方法
2020/09/04 PHP
CI框架给视图添加动态数据
2014/12/01 PHP
WordPress中对访客评论功能的一些优化方法
2015/11/24 PHP
在Thinkphp中使用ajax实现无刷新分页的方法
2016/10/25 PHP
PHP实现图片的等比缩放和Logo水印功能示例
2017/05/04 PHP
php下载远程大文件(获取远程文件大小)的实例
2017/06/17 PHP
jquery trim() 功能源代码
2011/02/14 Javascript
jQuery oLoader实现的加载图片和页面效果
2015/03/14 Javascript
JS与jQ读取xml文件的方法
2015/12/08 Javascript
JS中的数组方法笔记整理
2016/07/26 Javascript
js时间戳和c#时间戳互转方法(推荐)
2017/02/15 Javascript
Vue中的作用域CSS和CSS模块的区别
2018/10/09 Javascript
vue 实现特定条件下绑定事件
2019/11/09 Javascript
JavaScript oncopy事件用法实例解析
2020/05/13 Javascript
基于原生js实现判断元素是否有指定class名
2020/07/11 Javascript
[40:13]Ti4 冒泡赛第二天 iG vs NEWBEE 2
2014/07/15 DOTA
python中正则表达式的使用详解
2014/10/17 Python
Python使用shelve模块实现简单数据存储的方法
2015/05/20 Python
python实现简单遗传算法
2018/03/19 Python
python 用lambda函数替换for循环的方法
2018/06/09 Python
Python 查找list中的某个元素的所有的下标方法
2018/06/27 Python
python3 BeautifulSoup模块使用字典的方法抓取a标签内的数据示例
2019/11/28 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
2020/05/24 Python
如何让python的运行速度得到提升
2020/07/08 Python
jupyter notebook更换皮肤主题的实现
2021/01/07 Python
Python 中Operator模块的使用
2021/01/30 Python
CSS3中background-clip和background-origin的区别示例介绍
2014/03/10 HTML / CSS
HTML5 语义化结构化规范化
2008/10/17 HTML / CSS
印度尼西亚最大和最全面的网络商城:Blibli.com
2017/10/04 全球购物
英国最大的在线时尚眼镜店:Eyewearbrands
2019/03/12 全球购物
水产养殖学应届生求职信
2013/09/29 职场文书
重温入党誓词主持词
2015/06/29 职场文书
2016大一新生军训感言
2015/12/08 职场文书
oracle通过存储过程上传list保存功能
2021/05/12 Oracle