Python爬虫基础知识与项目实战
目录
一、Requests库
- Requests库介绍:提交爬取请求并爬取html网页,返回可供解析的对象。
- http(hypertext transfer protocol):超文本传输协议 ,采用url作为定位网络资源。
http://host[:port][path]
host:合法的Internet主机域名或IP地址
port:端口号,缺省端口为80
path:所请求资源的路径
http协议中对url的操作方法与requests库中的六个方法一致(获取、头信息、修改、删除)
3.Requests的七个主要方法
方法 | 说明 |
requests.request() | 构造爬虫请求,以下六个方法均自该方法基础上发展而来 |
requests.get() | 获取html页面 |
requests.head() | 获取html页面头信息 |
requests.post() | 添加资源,重复执行,效果累加 |
requests.put() | 更改资源,重复执行,覆盖重复字段 |
requests.patch() | 向html页面提交局部修改请求,会更新原有资源 |
requests.delete() | 向html页面提交删除请求 |
4.部分方法详解
4.1 requests.get()
- r=requests.get(url,params=None, **kwargs)
返回url链接对应的内容,为Response对象,**kwargs是可选参数,可以是header等
- Response对象的属性
属性 | 说明 |
r.status_code | 请求返回的状态,200表示链接成功 |
r.text | http响应内容的字符串形式,即url对应的内容 |
r.content | http响应内容的二进制形式 |
r.encoding | 从http header中猜测的响应内容编码方式 |
r.apparent_encodeing | 从http内容中分析出的响应内容编码方式 |
4.2post Vs put方法
二者都可以更改指定url的语义,但PUT被定义为idempotent的方法,即重复执行多次,产生的效果是一样的;POST则不是:
PUT请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源)
Post请求:后一个请求不会把第一个请求覆盖掉。(所以Post用来增资源)
4.3 requests.request(method,url,**kwargs)
requests库的基础方法,其他皆由此发展而来
method:请求方式,对应七种方法get/head/post/put/patch/delete/options
**kwargs:控制访问的参数,13个,在方法中一致
参数 | 数据类型 | 功能 |
params | 字典或字节 | 作为参数增加到url中 |
data | 字典或字节或文件对象 | 作为Requests的内容反馈到服务器 |
json | JSON格式的数据 | 作为Requests的内容反馈到服务器 |
headers | 字典 | HTTP定制头信息,可用于更改用户(Mozilla/5.0),易于简单爬取 |
cokkies | 字典或cokkie Jar | Requests中的cookie |
auth | 元组 | 支持http的认证功能 |
files | 字典 | 用于向服务器传输文件 ex:fs={‘file’:open('data.txt','rb')} r=requests.request('POST',url,files=fs) |
timeout | 数字,单位s | 设置超时时间,防止时间过长的无效爬取 |
prixies | 字典 | 设定访问代理服务器,可以增加登录认证(防止爬虫逆追踪) |
allow_redirects | 布尔 | 默认True,重定向开关 |
stream | 布尔 | 默认True,获取内容后立即下载 |
verify | 布尔 | 默认True,认证SSL证书开关 |
cert | 保证本地证书 路径 |
二、爬虫的Robots.txt
1.网络爬虫的限制
来源审查:检查来访http协议头的User-Agent域,只响应浏览器或友好爬虫访问,常可定义为
Mozilla/5.0
发布公告:Robots协议 ,建议遵守的爬取策略(哪些可以爬,哪些不能),一般位于网站根目录的robots.txt下。
2.在Robots协议中,#表示注释,*代表所有,/代表根目录
3.建议在进行 较大访问且访问频繁的爬虫时,遵守robots协议
三、Beautiful Soup库
from bs4 import BeautifulSoup(注意大小写),从bs4中引入BeautifulSoup类
Beautiful Soup库(bs4)是解析、遍历、维护“标签树”的功能库
BeautifulSoup类对应html/xml文档的全部内容,解析html如下:
soup=BeautifulSoup(r,’html.parser')
1.BeautifulSoup类的基本元素:标签
<p class="title"> ... </p>
基本元素 | 说明 | 格式 |
Tag | 标签,以<>开头和</>结尾;最基本的信息组织单元; | soup.<Tag>返回完整标签信息(此处Tag可以是标签的名字) |
Name | 标签名,<p>..</p>的名字为p,字符串类型 | <Tag>.name返回标签名字p |
Attributes | 标签属性,字典形式 | <Tag>.attrs,返回{“class”:“title”} |
NavigableString | 标签内非属性的字符串 | <Tag>.string,返回... |
Comment | 标签内字符串的注释部分 |
html是通过预定义标签的不同形式来组织不同类型的信息的
2. 信息标记的三种类型:
信息标记 | 标记形式 | 说明 |
XML | <name>...</name>,<name/>,<!--注释--> | 最早的通用信息标记语言,可扩展性好,但繁琐 |
JSON | 键值对,由嵌套表达所属关系 | 信息有类型,适合程序处理(js),较XML更简洁 |
YAML | 无类型键值对,由缩进表达所属关系,-表示并列关系,#表示注释, |表示整块数据 | 信息无类型,文本信息比例高,可读性好 |
3.基于bs4库的HTML内容遍历
HTML以标签树的形似存在,即标签对及其所属关系,遍历方式可分为下行遍历、上行遍历、平行遍历
遍历类型 | 属性 | 说明 |
下行遍历 | .contents | 子节点列表(下一代) |
.children | 子节点,迭代类型(下一代) | |
.descendants | 所有子孙节点,迭代类型 | |
上行遍历 | .parent | 父节点标签 |
.parents | 所有先辈标签,迭代类型,包括该标签 | |
平行遍历 | .next_sibling | 返回按照html文本顺序的下一个平行节点标签 |
.previous_sibling | 返回按照html文本顺序的上一个平行节点标签 | |
.next_siblings | 返回按照html文本顺序的后续所有平行节点标签,迭代类型 | |
.previous_siblingss | 返回按照html文本顺序的前续所有平行节点标签,迭代类型 |
迭代类型:可直接遍历
for children in soup.a.children
print(children)
4.soup.prettify()
为html文本<>及其内容自动增加‘\n’,使结果可读性更强
注:Python 3.x默认支持utf-8编码,可解析中文无障碍
5.信息提取
方式一:解析(XML,JSON,YAML)的标记形式→提取标记对应的信息
繁琐,慢,但信息解析准确
方式二:无视标记,直接搜索,即对信息的文本使用查找函数(拿到任务后可以先在源代码处手动 搜索一下)
准确性与文本内容相关,但很快,过程简洁
方法三(融合):先解析,遍历需要的标签,然后小范围搜索
html内容查找方法:
<>.find_all(name,attrs,recursive,string,**kwargs)#返回列表类型,存储查找到的结果
名字、属性、子孙、字符串等检索,可扩展
方法 说明 <>.find() 搜索且只返回第一个结果,参数同上 <>.find_parents() 在先辈节点中搜索,返回列表类型 <>.find_parent() 在先辈节点中搜索,返回一个结果 <>.find_next_siblings() 在后续平行节点中搜索,返回列表类型 <>.find_next_sibling() 在后续平行节点中搜索,返回一个结果 <>.find_previous_siblings() 在前续平行节点中搜索,返回列表类型 <>.find_previous_sibling() 在前续平行节点中搜索,返回一个结果
四、正则表达式
正则表达式是用来简洁表示一组字符串的表达式,即通用的字符串表达框架。
主要应用于字符串匹配中。
正则表达式的语法:字符+操作符
使用方式:导入re包,赋值r‘正则表达式’→原生字符串类型,其中的\不表示转义
正则表达式的操作符
操作符 | 说明 |
. | 表示任意单个字符 |
[] | 字符集,对单个字符的取值范围 |
[^] | 字符集,对单个字符给出排除范围 |
* | 前一字符的0或无限次扩展/最小匹配 |
+ | 前一字符的1或无限次扩展/最小匹配 |
? | 前一字符的0或1次扩展/最小匹配 |
{m,n} | 前一字符扩展m至n次(包含n)/最小匹配 |
{m} | 前一字符扩展m次 |
| | 左右表达式中的r任一个 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
() | 分组标记,内部只能使用|操作符 |
\d | 数字,等价于[0-9] |
\D | 数字,等价于[^0-9] |
\w | 单词字符,等价于[A-Za-z0-9] |
\b | 匹配空字符串,只能在单词的开始和结尾 |
\B | 匹配空字符串,但不能在开头和结尾 |
Re库的主要功能函数
首先,将正则表达式编译的正则表达式对象
regex=re.compile(正则表达式,flags=0)
对regex调用功能函数(常用)
函数 | 说明 |
regex.search() | 在一个字符中搜索匹配regex的第一个位置,返回match对象 |
regex.match() | 从一个字符的开始匹配regex,返回match对象 |
regex.findall() | 搜索字符串,以列表类型返回全部可以匹配的字符串 |
regex.split() | 将一个字符串按照正则表达式进行分割,返回列表类型 |
regex.finditer() | 搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素都是match对象 |
regex.sub() | 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串 |
Re库的Match对象
match对象是一次匹配的结果包含匹配的很多信息:
match=re.search(r'[1-9]\d{5}','BIT 100081')#返回BIT 100081中匹配上'[1-9]\d{5}'的部分
方法 | match.group(0) | 获取匹配后的字符串 |
match.start() | 匹配字符串在str中的开始位置 | |
match.end() | 匹配字符串在str中的结束位置 | |
match.apan() | 返回(.strat(),.end()) | |
属性 | match.string | 待匹配文本(BIT 100081) |
match.re | 待匹配正则表达式(re.complie('[1-9]\d{5}') | |
match.pos | 匹配结果在str中的开始位置 | |
match.endpos | 匹配结果在str中的结束位置 |
匹配:贪婪匹配和最小匹配(由于正则表达式中有无限次扩展形式引出)
贪婪匹配:输出匹配最长的字符串
最小匹配:输出匹配最短的字符串(在有扩展功能的操作符后加?)
五、项目实战(佛系更新...)
简单项目1-10
较复杂项目
本阶段在爬虫的目标信息获取上需要下重点