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文件夹与文件的操作实现代码
Jul 13 Python
Python实现类的创建与使用方法示例
Jul 25 Python
Python 关于反射和类的特殊成员方法
Sep 14 Python
Python 获得13位unix时间戳的方法
Oct 20 Python
pytorch对可变长度序列的处理方法详解
Dec 08 Python
python使用knn实现特征向量分类
Dec 26 Python
Python实现的列表排序、反转操作示例
Mar 13 Python
Python爬取破解无线网络wifi密码过程解析
Sep 17 Python
Python class的继承方法代码实例
Feb 14 Python
40行Python代码实现天气预报和每日鸡汤推送功能
Feb 27 Python
pycharm中如何自定义设置通过“ctrl+滚轮”进行放大和缩小实现方法
Sep 16 Python
Python 实现定积分与二重定积分的操作
May 26 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
别人整理的服务器变量:$_SERVER
2006/10/20 PHP
php file_exists 检查文件或目录是否存在的函数
2010/05/10 PHP
PHP 验证码的实现代码
2011/07/17 PHP
php+js iframe实现上传头像界面无跳转
2014/04/29 PHP
深入了解PHP中的Array数组和foreach
2016/11/06 PHP
转一个日期输入控件,支持FF
2007/04/27 Javascript
JavaScript更改class和id的方法
2008/10/10 Javascript
javascript淡入淡出效果的实现思路
2012/03/31 Javascript
js取整数、取余数的方法
2014/05/11 Javascript
简介JavaScript中fixed()方法的使用
2015/06/08 Javascript
seajs学习教程之基础篇
2016/10/20 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
页面间固定参数,通过cookie传值的实现方法
2017/05/31 Javascript
JS中将多个逗号替换为一个逗号的实现代码
2017/06/23 Javascript
swiper插件自定义切换箭头按钮
2017/12/28 Javascript
10 种最常见的 Javascript 错误(频率最高)
2018/02/08 Javascript
微信小程序textarea层级过高的解决方法
2019/03/04 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
微信小程序实现定位及到指定位置导航的示例代码
2019/08/20 Javascript
微信小程序tab切换可滑动切换导航栏跟随滚动实现代码
2019/09/04 Javascript
vue移动端下拉刷新和上滑加载
2020/10/27 Javascript
python编程开发之日期操作实例分析
2015/11/13 Python
利用Python爬虫给孩子起个好名字
2017/02/14 Python
Python3爬虫学习之爬虫利器Beautiful Soup用法分析
2018/12/12 Python
selenium WebDriverWait类等待机制的实现
2020/03/18 Python
Python基于数列实现购物车程序过程详解
2020/06/09 Python
Python 忽略文件名编码的方法
2020/08/01 Python
selenium学习教程之定位以及切换frame(iframe)
2021/01/04 Python
css3 clip实现圆环进度条的示例代码
2018/02/07 HTML / CSS
能否解释一下XSS cookie盗窃是什么意思
2012/06/02 面试题
外联部演讲稿
2014/05/24 职场文书
新闻编辑求职信
2014/07/13 职场文书
房屋租赁协议书
2014/10/18 职场文书
2015年党风廉政建设责任书
2015/01/29 职场文书
功夫熊猫观后感
2015/06/10 职场文书
2015年国庆节寄语
2015/08/17 职场文书