【问题1】什么是爬虫?:请求网站并提取数据的自动化程序

  • 爬虫法律不被禁止,但具有违法风险
  • 善意爬虫、恶意爬虫
  • 爬虫带来的风险:
    • 爬虫干扰了被访问网站的正常运营
    • 爬虫爬取了受到法律保护的特定类型的数据或信息
  • 如何避免爬虫风险:
    • 不时的优化自己的程序,避免干扰被访问网站的正常运行
    • 如爬取得数据,涉及到用户隐私商业机密等敏感内容需要及时停止爬取或传播

      爬虫基本流程

  1. 发起请求
  2. 获取响应内容
  3. 解析内容
  4. 保存数据

request与response
我→服务器:request
我←服务器:response

  1. 浏览器发送消息给该网址所在的服务器,这个过程叫做 HTTP Request
  2. 服务器收到浏览器发送的消息后,能够根据浏览器发送消息的内容,做相应处理,然后把消息回传给浏览器,这个过程叫做 HTTP Response
  3. 浏览器收到服务器的 response 信息后,会对信息进行相应处理,然后展示

    request 有什么?

  • 请求方式:主要有 GET、POST 两种类型,另外还有 HEAD、PUT、DELETE、OPTIONS等
  • 请求 URL:全称统一资源定位符,如一个网页文档、图片、视频都可以用一个 URL 唯一来确定
  • 请求头:包含请求时的头部信息,如 User-Agent、Host、Cookies等信息
  • 请求体:请求时额外携带的数据,如表单提交时的表单数据

    response 有什么?

  • 响应状态:有多种响应状态,如200代表成功,301跳转、404找不到页面,502服务器错误

  • 响应头:如内容类型、内容长度、服务器信息、设置Cookie等等
  • 响应体:最主要的部分,包含了请求资源的内容,如网页HTML、图片二进制数据等

    【考点】GET 与 POST 的区别

  • GET 的参数包含在 URL 中,POST 则不是

  • GET 请求的网页,在地址栏里可直接回车访问

    可爬取数据类型

  • 网页文本:如HTML文档,Json格式文本等

  • 图片:获取到的二进制文件、保存为图片格式
  • 视频:二进制文件,保存为视频格式
  • 其他:只要能请求的,都能获取

    解析方式

  • 直接处理

  • Json 解析
  • 正则表达式
  • BeautifulSoup
  • PyQuery
  • XPath

爬虫分类

  • 通用爬虫:抓取系统重要组成部分,抓取的是一整张页面数据
  • 聚焦爬虫:建立在通用爬虫基础上,抓取的是页面特定的局部内容
  • 增量式爬虫:检测网站钟数据更新的情况,只要抓取网站钟最新更新出来的数据
  • 分布式爬虫:提高爬虫效率的终极武器

反爬机制:门户网站,可以通过制定相应的策略或者技术手段,防止爬虫程序进行网站数据的爬取

反反爬策略:爬虫程序可以制定相关地 策略或者技术手段,破解门户网站钟具备的反爬机制

  • UA伪装:抓包工具获取User-Agent

http(超文本传输)协议

  • 概念:服务器与客户端进行数据交互的一种形式
  • 常用请求头信息
    • User-Agent:请求载体的身份标识
    • Connection:请求完毕后,是断开连接还是保持连接
  • 常用响应头信息
    • Content-Type:服务器响应回客户端的数据类型

https协议

  • 安全的超文本传输协议
  • 加密方式:
    • 对称密钥加密
    • 非对称密钥加密
    • 证书密钥加密

什么是 User-Agent?

  • 请求载体(同一设备浏览器浏览器-统一固定/爬虫程序-各不同)

image.pngimage.png

数据解析

聚集爬虫:爬取页面中指定的页面内容
解析分类:

  • 正则
  • bs4
  • xpath(通用其他语言)

数据解析原理:

  • 解析的局部的文本内容都会在标签之间或者标签对应的属性中进行存储
  • 1、进行指定标签的定位
  • 2、标签或者标签对应的属性中存储的数据值进行提取(解析)

编码流程:

  • 指定URL
  • 发起请求
  • 获取响应数据
  • 数据解析
  • 持久化存储

初识爬虫与BeautifulSoup

简单示例
from urllib.request import urlopen
html=urlopen(“http://pythonscraping.com/pages/page1.html“)
print(html.read())
保存为test.py文件终端运行:python test.py
这会输出.html源码,没什么用

from urllib.request import urlopen
urllib库:标准库,从网络请求数据,处理cookie,改变元数据(请求头和用户代理等)
Python文档:https://docs.python.org/3/library/urllib.html
urlopen库:用来打开并读取一个从网络获取的远程对象。一个非常通用的库(它可以轻松读取HTML文件、图像文件,或其他任何文件流)。

BeautifulSoup
非标准库,最新版本:BeautifulSoup 4

1、安装
>pip install beautifulsoup4

2、使用虚拟环境保存库文件
创建虚拟环境:$ virtualenv scrapingEnv
或者使用Anaconda轻松创建、管理虚拟环境。
激活虚拟环境:
$ cd scrapingEnv/
$ source bin/activate
或者把Python加入环境变量直接activate scrapingEnv
退出虚拟环境:deactivate
在虚拟环境安装库:激活环境>安装库
虚拟环境可打包分享传递

3、运行BeautifulSoup
from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen(“http://www.pythonscraping.com/pages/page1.html“)
bsObj=BeautifulSoup(html.read())
print(bsObj.h1)
结果:

AnInteresting Title


可用html.read()读取网页的HTML内容
•html→……
—head→AUsefulPage<title></head><br />—title→<br />—body→<body><h1>AnInt…</h1><div>Loremip…</div></body><br />—h1→<h1>AnInterestingTitle</h1><br />—div→<div>LoremIpsumdolor…</div><br />可一一读取:<br />bsObj.h1<br />bsObj.html.body.h1<br />bsObj.body.h1<br />bsObj.html.h1</p> <p>可能出现的异常<br />•网页在服务器上不存在(或者获取页面的时候出现错误)<br />•服务器不存在<br />处理方法:<br /><img src="https://cdn.nlark.com/yuque/0/2020/png/2981571/1606719405328-58130e2f-b50e-4bb2-83f4-7ff2a3a022de.png#crop=0&crop=0&crop=1&crop=1&height=965&id=R7fZH&originHeight=965&originWidth=1060&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=1060" alt=""><br />在写爬虫的时候,思考代码的总体格局,让代码既可以捕捉异常又容易阅读,这是很重要<br />的。如果你还希望能够很大程度地重用代码,那么拥有像getSiteHTML和getTitle这样的<br />通用函数(具有周密的异常处理功能)会让快速稳定地网络数据采集变得简单易行。</p> <p><strong>复杂的HTML解析</strong></p> <p><spanclass="green"></span><br />而另一些标签看起来是这样:<br /><spanclass="red"></span></p> <p>创建BeautifulSoup对象,抓取整个页面<br />from urllib.request import urlopen<br />from bs4 import BeautifulSoup<br />html=urlopen(“<a rel="nofollow" href="http://www.pythonscraping.com/pages/warandpeace.html">http://www.pythonscraping.com/pages/warandpeace.html</a>“)<br />bsObj=BeautifulSoup(html)</p> <p>用函数findall抽取绿色的人物名<br />nameList=bsObj.findAll(“span”,{“class”:”green”})<br />for name in nameList:<br />print(name.get_text())<br />bsObj.findAll(tagName,tagAttributes)获取指定标签<br /><img src="https://cdn.nlark.com/yuque/0/2020/png/2981571/1606719405385-9163d09b-465f-434b-8f05-16454e70a5e5.png#crop=0&crop=0&crop=1&crop=1&height=359&id=DkjL4&originHeight=359&originWidth=974&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=974" alt=""></p> <p><strong>BeautifulSoup的find()和findAll()</strong><br />findAll(tag,attributes,recursive,text,limit,keywords)<br />find(tag,attributes,recursive,text,keywords)<br />参数:<br />tag-标签或标签列表<br />attributes-标签属性及其属性值<br />recursive-布尔变量(True/False),查找所有标签/查找一级标签<br />text―它是用标签的文本内容去匹配,而不是用标签的属性。<br />limit,显然只用于findAll方法。find其实等价于findAll的limit等于<br />1时的情形。<br />keyword,可以让你选择那些具有指定属性的标签。例如:<br />allText=bsObj.findAll(id=”text”)<br />print(allText[0].get_text())<br /><img src="https://cdn.nlark.com/yuque/0/2020/png/2981571/1606719405443-5493ceee-79cf-422b-8609-c3c0d28713a1.png#crop=0&crop=0&crop=1&crop=1&height=1007&id=fiM3t&originHeight=1007&originWidth=979&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=979" alt=""></p> <p><strong>其他BeautifulSoup对象</strong><br />除了前面提到的:</p> <ul> <li>BeautifulSoup对象:前面代码示例中的bsObj</li><li>标签Tag对象</li></ul> <p>其它的对象(了解):</p> <ul> <li>NavigableString对象:用来表示标签里的文字,不是标签(有些函数可以操作和生成NavigableString对象,而不是标签对象)。</li><li>Comment对象:用来查找HTML文档的注释标签,<!--像这样--> <a name="KSyxO"></a><h1 id="boq71y"><a name="boq71y" class="reference-link"></a><span class="header-link octicon octicon-link"></span> </h1></li></ul> <p><a name="aybcZ"></a></p> <h1 id="8dchbb"><a name="8dchbb" class="reference-link"></a><span class="header-link octicon octicon-link"></span> </h1>