爬虫学习笔记
爬虫学习笔记
一、静态网页爬取
所需模块:
- requests
基本操作:
获取响应内容:requests.get()
第一个参数填url
link = 'http://baidu.com'
r.text 是服务器响应的内容,会根据响应头的字符编码进行解码
r.encoding 是服务器内容使用的文本编码
r.status_code 适用于检测响应的状态码,200表示成功
r.content是字节方式的响应体,自动解码gzip和deflate编码的响应数据
传递url参数:
key_dict = {'key1': 'valuel', 'key2': 'value2'}
r = requests.get(link, params = key_dict)
定制请求头:
首先,用google chrome的检查命令查看Requsts Headers
提取出来写入代码:
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0/2743.82 Safari/537.36', 'Host': 'www.santostang.com'}
r = requests.get(link, headers=headers)
发送POST请求:
将requests.get换为requests.post就可以了
超时:
设定长时间服务器不返回时返回异常的时间间隔
r = (link, timeout = 0.001)
二、动态网页爬取
- 通过浏览器审查元素解析地址(直接用chrome检查的Network选项抓包)
- 通过Selenium模拟浏览器抓取(之后详见专项)
三、编码问题
字符编码常识
字符编码有两大类:
- 通用的 Unicode 编码
- 将 Unicode 转化为某种类型的编码,如 UTF-8, GBK 等
ASCII: 一个字节,仅适用于英文字符表达的编码
Unicode: 两个字节,统一码、万国码
UTF-8:UTF(Unicode Transformation Format),长度可变,1~4字节,英文字母通常1个字节,汉字通常 3 个字节,单字节字符首位为 0 后面 7 位和 Unicode 码,因此英文字符 UTF-8 和 ASCII 是相同的,n 字节字符(n > 1)第一个字节的前 n 位都设为 1 ,第 n + 1 位设为 0,后面字节的前两位一律设为 10,剩下的没有提及的二进制位全部为 Unicode 码
Python 中的字符编码
Python 3 中,字符串编码使用 str 和 bytes 两种类型:
- str:使用 Unicode
- bytes:将 Unicode 转化为某种类型的编码,UTF-8、GBK 等
如何实现这两种类型的相互转换?使用 encode & decode!
encode: 将 Unicode 转换为其他编码规范
decode: 将其他编码的字符串转换为 Unicode
爬虫常见乱码问题
-
网站中文显示乱码:
- 原因:requests 基于 HTTP 头部推测的编码和真正编码不一致产生的乱码
- 解决:阅读网页代码,找到真正的编码格式
-
非法字符抛出:
- 原因:网页编码不规范,一个页面使用了多种编码
- 解决:使用 ignore 模式(默认情况下为 strict )忽略调少部分不规范编码,例子:
str.decode('GBK', 'ignore')
-
网页使用 gzip 压缩:
-
原因:网页使用 gzip 将网页压缩,需要先解压缩
-
解决:
会自动解码 gzip 和 deflate 传输的相应数据,可以先使用 chardet 找到字符串的编码,再把字符串解码为 Unicode 就行了:r.content
import chardet after_gzip = r.content print('解压后的字符串编码为',chardet.detect(after_gzip)) print(after_gzip.decode('{}'.format(chardet.detect(after_gzip))))
-
-
读写文件中的中文乱码:
- 原因:文件编码时读写不统一
- 解决:统一编码
四、解析网页
正则表达式
常见正则字符和含义
模式 | 描述 | 模式 | 描述 |
---|---|---|---|
. | 匹配除换行符外任意字符 | \s | 匹配空白字符 |
* | 匹配前一个字符 0 ~ n 次 | \S | 匹配非空白字符 |
+ | 匹配前一个字符 1 ~ n 次 | \d | 匹配数字,等价于[0-9] |
? | 匹配前一个字符 0 ~ 1 次 | \D | 匹配非数字,等价于[^0-9] |
^ | 匹配字符串开头 | \w | 匹配字母数字 |
$ | 匹配字符串末尾 | \W | 匹配非字母数字 |
() | 匹配括号内表达式,也表示一个组 | [] | 用来表示一组字符 |
re.match方法
re.match(pattern, string, flags=0)
从字符串起始位置匹配,若无法匹配,返回none
参数:
- pattern:正则式
- string:待匹配字符串
- flags:匹配方式(是否区分大小写、多行匹配)
例子:
m = re.match('www', 'www.baidu.com')
print(m)
print(m.span())
print(m.start())
print(m.end())
# 输出为:
# <re.Match object; span=(0, 3), match='www'>
# 0
# 3
str = 'Fat cat are smarter than dogs, is it right?'
m = re.match(r'(.*) are (.*) dogs', str)
print(m.group())
print(m.group(1))
print(m.group(2))
print(m.groups())
# 输出为:
# Fat cat are smarter than dogs
# Fat cats
# smarter than
# ('Fat cats', 'smarter than')
re.search方法
这个方法会扫描整个字符串并返回第一个成功的匹配
re.findall方法
扫描整个字符串并返回所有匹配(返回一个list,list里面有好多tuple)
Beautiful Soup
这玩意儿可以从HTML或XML文件种提取数据。
安装
模块名为bs4,直接 pip 或者 conda
用法
自己查官方文档
五、数据存储
六、程序运行的基本知识
并发 & 并行
并发:同一时间段发生,单核CPU,各个任务分别占用CPU一段时间依次执行
并行:同一时刻发生,多核CPU,同时处理多个任务
同步 & 异步
同步: 任务间有先后顺序,一个任务进行完毕后再进行另一个任务
异步:任务间相互独立,任务可同时进行,速度远超同步
七、多线程爬虫
执行方式:并发
主要模块:threading, queue
简述:
Python为数据安全设有GIL (Global Interpreter Lock),一个线程的执行过程为:获取GIL、执行代码直到挂起、释放GIL,而在一个Python进程中,GIL只有一个,没有GIL的线程不允许进入CPU。
每次释放GIL时,线程之间会进行竞争,而切换线程会消耗资源,所以在多核CPU上Python的多线程效率不高。
但是对于IO密集型网络爬虫来说,IO操作会进行IO等待,开启多线程能够利用IO等待的时间切换线程进行任务,所以提升执行效率。
Python多线程学习笔记:戳这里
八、多进程爬虫
执行方式:并行
主要模块:multiprocessing
简述:不同于多线程受制于 GIL 的限制,多进程爬虫可以充分利用 CPU 的多核,主要使用的方法是 Procee + Queue 或者 Pool + Queue
Python多进程学习笔记:戳这里
九、多协程爬虫
Python多协程学习笔记:戳这里
十、突破反爬虫

原文链接:爬虫学习笔记
nightmorning的博客 版权所有,转载请注明出处。
还没有任何评论,你来说两句吧!