Python-100-Days/Day66-75/02.数据采集和解析.md

128 lines
4.7 KiB
Markdown
Raw Normal View History

2018-05-28 08:50:30 +08:00
## 数据采集和解析
2018-05-29 01:48:26 +08:00
通过上一个章节,我们已经了解到了开发一个爬虫需要做的工作以及一些常见的问题,至此我们可以对爬虫开发需要做的工作以及相关的技术做一个简单的汇总,可能有些库我们之前并没有使用过,不过别担心,这些内容我们都会讲到的。
1. 下载数据 - urllib / requests / aiohttp。
2. 解析数据 - re / lxml / beautifulsoup4bs4/ pyquery。
2018-05-29 16:58:46 +08:00
3. 缓存和持久化 - pymysql / redis / sqlalchemy / peewee / pymongo。
2018-06-02 13:19:54 +08:00
4. 生成摘要 - hashlib。
5. 序列化和压缩 - pickle / json / zlib。
6. 调度器 - 进程 / 线程 / 协程。
2018-05-29 01:48:26 +08:00
2018-05-28 08:50:30 +08:00
### HTML页面分析
2018-05-29 01:48:26 +08:00
```HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>Hello, world!</h1>
<p>这是一个神奇的网站!</p>
<hr>
<div>
<h2>这是一个例子程序</h2>
<p>静夜思</p>
<p class="foo">床前明月光</p>
<p id="bar">疑似地上霜</p>
<p class="foo">举头望明月</p>
<div><a href="http://www.baidu.com"><p>低头思故乡</p></a></div>
</div>
<a class="foo" href="http://www.qq.com">腾讯网</a>
<img src="./img/pretty-girl.png" alt="美女">
<img src="./img/hellokitty.png" alt="凯蒂猫">
<img src="/static/img/pretty-girl.png" alt="美女">
<table>
<tr>
<th>姓名</th>
<th>上场时间</th>
<th>得分</th>
<th>篮板</th>
<th>助攻</th>
</tr>
</table>
</body>
</html>
```
如果你对上面的代码并不感到陌生那么你一定知道HTML页面通常由三部分构成分别是用来承载内容的Tag标签、负责渲染页面的CSS层叠样式表以及控制交互式行为的JavaScript。通常我们可以在浏览器的右键菜单中通过“查看网页源代码”的方式获取网页的代码并了解页面的结构当然我们也可以通过浏览器提供的开发人员工具来了解网页更多的信息。
#### 使用requests获取页面
1. GET请求和POST请求。
2. URL参数和请求头。
3. 复杂的POST请求文件上传
4. 操作Cookie。
2018-05-29 07:24:56 +08:00
5. 设置代理服务器。
6. 超时设置。
2018-05-29 01:48:26 +08:00
2018-05-29 07:24:56 +08:00
> 说明关于requests的详细用法可以参考它的[官方文档](http://docs.python-requests.org/zh_CN/latest/user/quickstart.html)。
2018-05-28 08:50:30 +08:00
2018-05-29 07:24:56 +08:00
### 四种采集方式
#### 四种采集方式的比较
2018-05-29 01:48:26 +08:00
| 抓取方法 | 速度 | 使用难度 | 备注 |
| ---------- | --------------------- | -------- | ------------------------------------------ |
| 正则表达式 | 快 | 困难 | 常用正则表达式<br>在线正则表达式测试 |
| lxml | 快 | 一般 | 需要安装C语言依赖库<br>唯一支持XML的解析器 |
| Beautiful | 快/慢(取决于解析器) | 简单 | |
2018-05-29 07:24:56 +08:00
| PyQuery | 较快 | 简单 | Python版的jQuery |
2018-05-29 01:48:26 +08:00
> 说明Beautiful的解析器包括Python标准库html.parser、lxml的HTML解析器、lxml的XML解析器和html5lib。
#### BeautifulSoup的使用
2018-05-28 08:50:30 +08:00
2018-05-29 07:24:56 +08:00
1. 遍历文档树
- 获取标签
- 获取标签属性
- 获取标签内容
- 获取子(孙)节点
- 获取父节点/祖先节点
- 获取兄弟节点
2. 搜索树节点
- find / find_all字符串、正则表达式、列表、True、函数或Lambda。
- select_one / selectCSS选择器
2018-06-08 16:31:02 +08:00
> 说明更多内容可以参考BeautifulSoup的[官方文档](https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html)。
2018-05-28 08:50:30 +08:00
2018-05-29 21:05:42 +08:00
### 实例 - 获取知乎发现上的问题链接
2018-05-29 16:58:46 +08:00
```Python
from urllib.parse import urljoin
import re
import requests
from bs4 import BeautifulSoup
def main():
headers = {'user-agent': 'Baiduspider'}
proxies = {
'http': 'http://122.114.31.177:808'
}
base_url = 'https://www.zhihu.com/'
seed_url = urljoin(base_url, 'explore')
resp = requests.get(seed_url,
headers=headers,
proxies=proxies)
soup = BeautifulSoup(resp.text, 'lxml')
href_regex = re.compile(r'^/question')
link_set = set()
for a_tag in soup.find_all('a', {'href': href_regex}):
if 'href' in a_tag.attrs:
href = a_tag.attrs['href']
full_url = urljoin(base_url, href)
link_set.add(full_url)
print('Total %d question pages found.' % len(link_set))
if __name__ == '__main__':
main()
```