Python网络爬虫二三事

1 前言

作为一名合格的数据分析师,其完整的技术知识体系必须贯穿数据获取、数据存储、数据提取、数据分析、数据挖掘、数据可视化等各大部分。在此作为初出茅庐的数据小白,我将会把自己学习数据科学过程中遇到的一些问题记录下来,以便后续的查阅,同时也希望与各路同学一起交流、一起进步。刚好前段时间学习了Python网络爬虫,在此将网络爬虫做一个总结。

2 何为网络爬虫?

2.1 爬虫场景

我们先自己想象一下平时到天猫商城购物(PC端)的步骤,可能就是打开浏览器==》搜索天猫商城==》点击链接进入天猫商城==》选择所需商品类目(站内搜索)==》浏览商品(价格、详情参数、评论等)==》点击链接==》进入下一个商品页面,……这样子周而复始。当然这其中的搜索也是爬虫的应用之一。简单讲,网络爬虫是类似又区别于上述场景的一种程序。

2.2 爬虫分类

  • 分类与关系
    一般最常用的爬虫类型主要有通用爬虫和聚焦爬虫,其中聚焦爬虫又分为浅聚焦与深聚焦,三者关系如下图:
  • 区别
    通用爬虫与聚焦爬虫的区别就在有没有对信息进行过滤以尽量保证只抓取与主题相关的网页信息。
  • 聚焦爬虫过滤方法
    • 浅聚焦爬虫
      选取符合目标主题的种子URL,例如我们定义抓取的信息为招聘信息,我们便可将招聘网站的URL(拉勾网、大街网等)作为种子URL,这样便保证了抓取内容与我们定义的主题的一致性。
    • 深聚焦爬虫
      一般有两种,一是针对内容二是针对URL。其中针对内容的如页面中绝大部分超链接都是带有锚文本的,我们可以根据锚文本进行筛选;针对URL的如现有链接http://geek.csdn.net/news/detail/126572 ,该链接便向我们透漏主题是新闻(news)。

2.3 爬虫原理

总的来说,爬虫就是从种子URL开始,通过 HTTP 请求获取页面内容,并从页面内容中通过各种技术手段解析出更多的 URL,递归地请求获取页面的程序网络爬虫,总结其主要原理如下图(其中红色为聚焦爬虫相对通用爬虫所需额外进行步骤):

当然,如果对于网络爬虫原理细节有兴趣的同学可参考一下两篇博文:
网络爬虫基本原理(一)
网络爬虫基本原理(二)

2.4 爬虫应用

网络爬虫可以做的事情很多,如以下列出:

  • 搜索引擎
  • 采集数据(金融、商品、竞品等)
  • 广告过滤
  • ……

其实就我们个人兴趣,学完爬虫我们可以看看当当网上哪种技术图书卖得比较火(销量、评论等信息)、看某个在线教育网站哪门网络课程做得比较成功、看双十一天猫的活动情况等等,只要我们感兴趣的数据,一般的话都可以爬取得到,不过有些网站比较狡猾,设置各种各样的反扒机制。总而言之,网络爬虫可以帮助我们做很多有趣的事情。

3 网络爬虫基础

个人建议本章除3.3以外,其他内容可以大致先看一下,有些许印象即可,等到后面已经完成一些简单爬虫后或者在写爬虫过程中遇到一些问题再回头来巩固一下,这样子或许更有助于我们进一步网络理解爬虫。

3.1 HTTP协议

HTTP 协议是爬虫的基础,通过封装 TCP/IP 协议链接,简化了网络请求的流程,使得用户不需要关注三次握手,丢包超时等底层交互。

关于HTTP协议可以参考一下博文:

3.2 前端技术

作为新手,个人觉得入门的话懂一点HTML与JavaScript就可以实现基本的爬虫项目,HTML主要协助我们处理静态页面,而实际上很多数据并不是我们简单的右击查看网页源码便可以看到的,而是存在JSON(JavaScript Object Notation)文件中,这时我们便需要采取抓包分析,详见《5.2 爬取基于Ajax技术网页数据》。

3.3 正则表达式与XPath

做爬虫必不可少的步骤便是做解析。正则表达式是文本匹配提取的利器,并且被各种语言支持。XPath即为XML路径语言,类似Windows的文件路径,区别就在XPath是应用在网页页面中来定位我们所需内容的精确位置。具体用法参考以下资料:

4 网络爬虫常见问题

4.1爬虫利器——python

Python 是一种十分便利的脚本语言,广泛被应用在各种爬虫框架。Python提供了如urllib、re、json、pyquery等模块,同时前人又利用Python造了许许多多的轮,如Scrapy框架、PySpider爬虫系统等,所以做爬虫Python是一大利器。

  • 说明:本章开发环境细节如下
    • 系统环境:windows 8.1
    • 开发语言:Python3.5
    • 开发工具:Spyder、Pycharm
    • 辅助工具:Chrome浏览器

4.2 编码格式

Python3中,只有Unicode编码的为str,其他编码格式如gbk,utf-8,gb2312等都为bytes,在编解码过程中字节bytes通过解码方法decode()解码为字符串str,然后字符串str通过编码方法encode()编码为字节bytes,关系如下图:

实战——爬取当当网

爬取网页

查看编码格式

可知爬取到的网页是GB2312编码,这是汉字的国标码,专门用来表示汉字。
解码

重编码

4.3 超时设置

  • 允许超时
  • 线程推迟(单位为秒)

4.4 异常处理

每个程序都不可避免地要进行异常处理,爬虫也不例外,假如不进行异常处理,可能导致爬虫程序直接崩掉。

4.4.1 网络爬虫中处理异常的种类与关系

  • URLError
    通常,URLError在没有网络连接(没有路由到特定服务器),或者服务器不存在的情况下产生。
  • HTTPError首先我们要明白服务器上每一个HTTP 应答对象response都包含一个数字“状态码”,该状态码表示HTTP协议所返回的响应的状态,这就是HTTPError。比如当产生“404 Not Found”的时候,便表示“没有找到对应页面”,可能是输错了URL地址,也可能IP被该网站屏蔽了,这时便要使用代理IP进行爬取数据,关于代理IP的设定我们下面会讲到。
  • 两者关系
    两者是父类与子类的关系,即HTTPError是URLError的子类,HTTPError有异常状态码与异常原因,URLError没有异常状态码。所以,我们在处理的时候,不能使用URLError直接代替HTTPError。同时,Python中所有异常都是基类Exception的成员,所有异常都从此基类继承,而且都在exceptions模块中定义。如果要代替,必须要判断是否有状态码属性。

4.4.2 Python中有一套异常处理机制语法

  • try-except语句

    • try 语句:捕获异常
    • except语句:处理不同的异常,Exception是异常的种类,在爬虫中常见如上文所述。
    • e:异常的信息,可供后面打印输出
    • else: 表示若没有发生异常,当try执行完毕之后,就会执行else
  • try-except-finally语句

    假如try没有捕获到错误信息,则直接跳过except语句转而执行finally语句,其实无论是否捕获到异常都会执行finally语句,因此一般我们都会将一些释放资源的工作放到该步中,如关闭文件句柄或者关闭数据库连接等。

4.4.3 实战——爬取CSDN博客

Exception异常捕获输出结果如下:

4.5 自动模拟HTTP请求

一般客户端需要通过HTTP请求才能与服务端进行通信,常见的HTTP请求有POST与GET两种。例如我们打开淘宝网页后一旦HTML加载完成,浏览器将会发送GET请求去获取图片等,这样子我们才能看到一个完整的动态页面,假如我们浏览后需要下单那么还需要向服务器传递登录信息。

  • GET方式
    向服务器发索取数据的一种请求,将请求数据融入到URL之中,数据在URL中可以看到。
  • POST方式向服务器提交数据的一种请求,将数据放置在HTML HEADER内提交。从安全性讲,POST方式相对于GET方式较为安全,毕竟GET方式是直接将请求数据以明文的形式展现在URL中。
  • 实战——登录CSDN/百度搜索简书

4.6 cookies处理

cookies是某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。

参考:零基础自学用Python 3开发网络爬虫(四): 登录

4.7 浏览器伪装

  • 原理
    浏览器伪装是防屏蔽的方法之一,简言之,其原理就是在客户端在向服务端发送的请求中添加报头信息,告诉服务器“我是浏览器”
  • 如何查看客户端信息?
    通过Chrome浏览器按F12==》选择Network==》刷新后点击Name下任一个地址,便可以看到请求报文和相应报文信息。以下是在百度上搜索简书的请求报文信息,在爬虫中我们只需添加报头中的User-Agent便可实现浏览器伪装。
  • 实战——爬取CSDN博客
    在上面的实例中我们已知道对CSDN博客直接进行爬取的时候会返回403错误,接下来将我们伪装成浏览器爬取CSDN博客

4.8 代理服务器

  • 原理
    代理服务器原理如下图,利用代理服务器可以很好处理IP限制问题。

    个人认为IP限制这一点对爬虫的影响是很大的,毕竟我们一般不会花钱去购买正规的代理IP,我们一般都是利用互联网上提供的一些免费代理IP进行爬取,而这些免费IP的质量残次不齐,出错是在所难免的,所以在使用之前我们要对其进行有效性测试。另外,对开源IP池有兴趣的同学可以学习Github上的开源项目:IPProxyPool
  • 实战——代理服务器爬取百度首页

4.9 抓包分析

  • Ajax(异步加载)的技术
    网站中用户需求的数据如联系人列表,可以从独立于实际网页的服务端取得并且可以被动态地写入网页中。简单讲就是打开网页,先展现部分内容,再慢慢加载剩下的内容。显然,这样的网页因为不用一次加载全部内容其加载速度特别快,但对于我们爬虫的话就比较麻烦了,我们总爬不到我们想要的内容,这时候就需要进行抓包分析。
  • 抓包工具
    推荐Fiddler与Chrome浏览器
  • 实战
    请转《5.2 爬取基于Ajax技术网页数据》。

4.10多线程爬虫

一般我们程序是单线程运行,但多线程可以充分利用资源,优化爬虫效率。实际上Python 中的多线程并行化并不是真正的并行化,但是多线程在一定程度上还是能提高爬虫的执行效率,下面我们就针对单线程和多线程进行时间上的比较。

  • 实战——爬取豆瓣科幻电影网页
  • 结果:
  • 更多详情请参考:
    Python 并行任务技巧
    Python中的多进程处理

4.11 数据存储

  • 本地文件(excel、txt)
  • 数据库(如MySQL)

备注:具体实战请看5.1

4.12 验证码处理

在登录过程中我们常遇到验证码问题,此时我们有必要对其进行处理。

5 综合实战案例

5.1 爬取静态网页数据

(1)需求

爬取豆瓣网出版社名字并分别存储到excel、txt与MySQL数据库中。

(2)分析

  • 查看源码
  • Ctrl+F搜索任意出版社名字,如博集天卷
  • 确定正则模式

(3)思路

  • 下载目标页面
  • 正则匹配目标内容
  • Python列表存储
  • 写入Excel/txt/MySQL

(4)源码

(5)结果

5.2 爬取基于Ajax技术网页数据

(1)需求

爬取拉勾网广州的数据挖掘岗位信息并存储到本地Excel文件中

(2)分析

  • 岗位数据在哪里?
    打开拉勾网==》输入关键词“数据挖掘”==》查看源码==》没发现岗位信息
    打开拉勾网==》输入关键词“数据挖掘”==》按F12==》Network刷新==》按下图操作

    我们可以发现存在position和company开头的json文件,这很可能就是我们所需要的岗位信息,右击选择open link in new tab,可以发现其就是我们所需的内容。

  • 如何实现翻页?
    我们在写爬虫的时候需要多页爬取,自动模拟换页操作。首先我们点击下一页,可以看到url没有改变,这也就是Ajax(异步加载)的技术。点击position的json文件,在右侧点击Headers栏,可以发现最底部有如下内容:

    当我们换页的时候pn则变为2且first变为false,故我们可以通过构造post表单进行爬取。

  • Json数据结构怎么样?

    (3)源码

5.3 利用Scrapy框架爬取

5.3.1 了解Scrapy

Scrapy使用了Twisted异步网络库来处理网络通讯。整体架构大致如下(注:图片来自互联网):

详情转Scrapy:Python的爬虫框架
关于Scrapy的使用方法请参考官方文档

5.3.2 Scrapy自动爬虫

前面的实战中我们都是通过循环构建URL进行数据爬取,其实还有另外一种实现方式,首先设定初始URL,获取当前URL中的新链接,基于这些链接继续爬取,直到所爬取的页面不存在新的链接为止。

(1)需求

采用自动爬虫的方式爬取糗事百科文章链接与内容,并将文章头部内容与链接存储到MySQL数据库中。

(2)分析

  • 怎么提取首页文章链接?
    打开首页后查看源码,搜索首页任一篇文章内容,可以看到”/article/118123230″链接,点击进去后发现这就是我们所要的文章内容,所以我们在自动爬虫中需设置链接包含”article”
  • 怎么提取详情页文章内容与链接
    • 内容
      打开详情页后,查看文章内容如下:

      分析可知利用包含属性class且其值为content的div标签可唯一确定文章内容,表达式如下:
      "//div[@class='content']/text()"

    • 链接打开任一详情页,复制详情页链接,查看详情页源码,搜索链接如下:
      采用以下XPath表达式可提取文章链接。
      ["//link[@rel='canonical']/@href"]

(3)项目源码

创建爬虫项目

打开CMD,切换到存储爬虫项目的目录下,输入:
scrapy startproject qsbkauto

  • 项目结构说明
    • spiders.qsbkspd.py:爬虫文件
    • items.py:项目实体,要提取的内容的容器,如当当网商品的标题、评论数等
    • pipelines.py:项目管道,主要用于数据的后续处理,如将数据写入Excel和db等
    • settings.py:项目设置,如默认是不开启pipeline、遵守robots协议等
    • scrapy.cfg:项目配置
创建爬虫

进入创建的爬虫项目,输入:
scrapy genspider -t crawl qsbkspd qiushibaie=ke.com(域名)

定义items

编写爬虫
  • qsbkauto.py
  • pipelines.py
  • setting.py关闭ROBOTSTXT_OBEY
    设置USER_AGENT
    开启ITEM_PIPELINES
执行爬虫

结果

参考:
[1] 天善社区韦玮老师课程
[2] 文中所跳转的URL
本文所有代码只用于技术交流,拒绝任何商用活动
文章相关项目代码已上传至个人Github
后续的学习细节将会记录在个人博客whenif中,欢迎各路同学互相交流

3 19 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部