提交 1326b2d0 编写于 作者: 骆昊的技术专栏's avatar 骆昊的技术专栏

更新了爬虫阶段的文档

上级 da492bb9
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
大多数网站都会定义robots.txt文件,下面以淘宝的[robots.txt](http://www.taobao.com/robots.txt)文件为例,看看该网站对爬虫有哪些限制。 大多数网站都会定义robots.txt文件,下面以淘宝的[robots.txt](http://www.taobao.com/robots.txt)文件为例,看看该网站对爬虫有哪些限制。
``` ```
User-agent: Baiduspider User-agent: Baiduspider
Allow: /article Allow: /article
Allow: /oshtml Allow: /oshtml
...@@ -89,7 +90,7 @@ Disallow: / ...@@ -89,7 +90,7 @@ Disallow: /
#### HTTP协议 #### HTTP协议
在开始讲解爬虫之前,我们稍微对HTTP(超文本传输协议)做一些回顾,因为我们在网页上看到的内容通常是浏览器执行HTML语言得到的结果,而HTTP就是传输HTML数据的协议。HTTP是构建于TCP(传输控制协议)之上应用级协议,它利用了TCP提供的可靠的传输服务实现了Web应用中的数据交换。按照维基百科上的介绍,设计HTTP最初的目的是为了提供一种发布和接收[HTML](https://zh.wikipedia.org/wiki/HTML)页面的方法,也就是说这个协议是浏览器和Web服务器之间传输的数据的载体。关于这个协议的详细信息以及目前的发展状况,大家可以阅读阮一峰老师的[《HTTP 协议入门》](http://www.ruanyifeng.com/blog/2016/08/http.html)[《互联网协议入门》](http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html)系列以及[《图解HTTPS协议》](http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html)进行了解,下图是我在2009年9月10日凌晨4点在四川省网络通信技术重点实验室用开源协议分析工具Ethereal(抓包工具WireShark的前身)截取的访问百度首页时的HTTP请求和响应的报文(协议数据),由于Ethereal截取的是经过网络适配器的数据,因此可以清晰的看到从物理链路层到应用层的协议数据。 在开始讲解爬虫之前,我们稍微对HTTP(超文本传输协议)做一些回顾,因为我们在网页上看到的内容通常是浏览器执行HTML语言得到的结果,而HTTP就是传输HTML数据的协议。HTTP是构建于TCP(传输控制协议)之上应用级协议,它利用了TCP提供的可靠的传输服务实现了Web应用中的数据交换。按照维基百科上的介绍,设计HTTP最初的目的是为了提供一种发布和接收[HTML](https://zh.wikipedia.org/wiki/HTML)页面的方法,也就是说这个协议是浏览器和Web服务器之间传输的数据的载体。关于这个协议的详细信息以及目前的发展状况,大家可以阅读阮一峰老师的[《HTTP 协议入门》](http://www.ruanyifeng.com/blog/2016/08/http.html)[《互联网协议入门》](http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html)系列以及[《图解HTTPS协议》](http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html)进行了解,下图是我在四川省网络通信技术重点实验室工作期间用开源协议分析工具Ethereal(抓包工具WireShark的前身)截取的访问百度首页时的HTTP请求和响应的报文(协议数据),由于Ethereal截取的是经过网络适配器的数据,因此可以清晰的看到从物理链路层到应用层的协议数据。
HTTP请求(请求行+请求头+空行+[消息体]): HTTP请求(请求行+请求头+空行+[消息体]):
...@@ -114,6 +115,7 @@ HTTP响应(响应行+响应头+空行+消息体): ...@@ -114,6 +115,7 @@ HTTP响应(响应行+响应头+空行+消息体):
3. HTTPie 3. HTTPie
```Shell ```Shell
$ http --header http://www.scu.edu.cn $ http --header http://www.scu.edu.cn
HTTP/1.1 200 OK HTTP/1.1 200 OK
Accept-Ranges: bytes Accept-Ranges: bytes
...@@ -136,6 +138,7 @@ HTTP响应(响应行+响应头+空行+消息体): ...@@ -136,6 +138,7 @@ HTTP响应(响应行+响应头+空行+消息体):
4. BuiltWith:识别网站使用的技术 4. BuiltWith:识别网站使用的技术
```Python ```Python
>>> >>>
>>> import builtwith >>> import builtwith
>>> builtwith.parse('http://www.bootcss.com/') >>> builtwith.parse('http://www.bootcss.com/')
...@@ -150,6 +153,7 @@ HTTP响应(响应行+响应头+空行+消息体): ...@@ -150,6 +153,7 @@ HTTP响应(响应行+响应头+空行+消息体):
5. python-whois:查询网站的所有者 5. python-whois:查询网站的所有者
```Python ```Python
>>> >>>
>>> import whois >>> import whois
>>> whois.whois('baidu.com') >>> whois.whois('baidu.com')
...@@ -159,6 +163,7 @@ HTTP响应(响应行+响应头+空行+消息体): ...@@ -159,6 +163,7 @@ HTTP响应(响应行+响应头+空行+消息体):
6. robotparser:解析robots.txt的工具 6. robotparser:解析robots.txt的工具
```Python ```Python
>>> from urllib import robotparser >>> from urllib import robotparser
>>> parser = robotparser.RobotFileParser() >>> parser = robotparser.RobotFileParser()
>>> parser.set_url('https://www.taobao.com/robots.txt') >>> parser.set_url('https://www.taobao.com/robots.txt')
...@@ -186,6 +191,7 @@ HTTP响应(响应行+响应头+空行+消息体): ...@@ -186,6 +191,7 @@ HTTP响应(响应行+响应头+空行+消息体):
7. 将有用的信息进行持久化(以备后续的处理)。 7. 将有用的信息进行持久化(以备后续的处理)。
```Python ```Python
from urllib.error import URLError from urllib.error import URLError
from urllib.request import urlopen from urllib.request import urlopen
...@@ -280,7 +286,7 @@ if __name__ == '__main__': ...@@ -280,7 +286,7 @@ if __name__ == '__main__':
2. 设置代理服务。有些网站会限制访问的区域(例如美国的Netflix屏蔽了很多国家的访问),有些爬虫需要隐藏自己的身份,在这种情况下可以设置代理服务器(urllib.request中的ProxyHandler就是用来进行此项操作)。 2. 设置代理服务。有些网站会限制访问的区域(例如美国的Netflix屏蔽了很多国家的访问),有些爬虫需要隐藏自己的身份,在这种情况下可以设置代理服务器(urllib.request中的ProxyHandler就是用来进行此项操作)。
3. 限制下载速度。如果我们的爬虫获取网页的速度过快,可能就会面临被封禁或者产生“损害动产”的风险(这个可能会导致吃官司且败诉),可以在两次下载之间添加延时从而对爬虫进行限速。 3. 限制下载速度。如果我们的爬虫获取网页的速度过快,可能就会面临被封禁或者产生“损害动产”的风险(这个可能会导致吃官司且败诉),可以在两次下载之间添加延时从而对爬虫进行限速。
4. 避免爬虫陷阱。有些网站会动态生成页面内容,这会导致产生无限多的页面(例如在线万年历等)。可以通过记录到达当前页面经过了多少个链接(链接深度)来解决该问题,当达到事先设定的最大深度时爬虫就不再像队列中添加该网页中的链接了。 4. 避免爬虫陷阱。有些网站会动态生成页面内容,这会导致产生无限多的页面(例如在线万年历等)。可以通过记录到达当前页面经过了多少个链接(链接深度)来解决该问题,当达到事先设定的最大深度时爬虫就不再像队列中添加该网页中的链接了。
...@@ -289,6 +295,7 @@ if __name__ == '__main__': ...@@ -289,6 +295,7 @@ if __name__ == '__main__':
- 使用未经验证的上下文 - 使用未经验证的上下文
```Python ```Python
import ssl import ssl
request = urllib.request.Request(url='...', headers={...}) request = urllib.request.Request(url='...', headers={...})
...@@ -299,6 +306,7 @@ if __name__ == '__main__': ...@@ -299,6 +306,7 @@ if __name__ == '__main__':
- 设置全局的取消证书验证 - 设置全局的取消证书验证
```Python ```Python
import ssl import ssl
ssl._create_default_https_context = ssl._create_unverified_context ssl._create_default_https_context = ssl._create_unverified_context
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
### HTML页面分析 ### HTML页面分析
```HTML ```HTML
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
...@@ -64,12 +65,12 @@ ...@@ -64,12 +65,12 @@
#### 四种采集方式的比较 #### 四种采集方式的比较
| 抓取方法 | 速度 | 使用难度 | 备注 | | 抓取方法 | 速度 | 使用难度 | 备注 |
| ---------- | --------------------- | -------- | ------------------------------------------ | | ---------- | ------------------------- | -------- | ------------------------------------------ |
| 正则表达式 | 快 | 困难 | 常用正则表达式<br>在线正则表达式测试 | | 正则表达式 | 快 | 困难 | 常用正则表达式<br>在线正则表达式测试 |
| lxml | 快 | 一般 | 需要安装C语言依赖库<br>唯一支持XML的解析器 | | lxml | 快 | 一般 | 需要安装C语言依赖库<br>唯一支持XML的解析器 |
| Beautiful | 快/慢(取决于解析器) | 简单 | | | Beautiful | 较快/较慢(取决于解析器) | 简单 | |
| PyQuery | 较快 | 简单 | Python版的jQuery | | PyQuery | 较快 | 简单 | Python版的jQuery |
> 说明:Beautiful的解析器包括:Python标准库(html.parser)、lxml的HTML解析器、lxml的XML解析器和html5lib。 > 说明:Beautiful的解析器包括:Python标准库(html.parser)、lxml的HTML解析器、lxml的XML解析器和html5lib。
...@@ -91,6 +92,7 @@ ...@@ -91,6 +92,7 @@
### 实例 - 获取知乎发现上的问题链接 ### 实例 - 获取知乎发现上的问题链接
```Python ```Python
from urllib.parse import urljoin from urllib.parse import urljoin
import re import re
......
...@@ -220,7 +220,9 @@ Python3.2带来了`concurrent.futures` 模块,这个模块包含了线程池 ...@@ -220,7 +220,9 @@ Python3.2带来了`concurrent.futures` 模块,这个模块包含了线程池
上面的代码使用了[AIOHTTP](https://github.com/aio-libs/aiohttp)这个非常著名的第三方库,它实现了HTTP客户端和HTTP服务器的功能,对异步操作提供了非常好的支持,有兴趣可以阅读它的[官方文档](https://aiohttp.readthedocs.io/en/stable/) 上面的代码使用了[AIOHTTP](https://github.com/aio-libs/aiohttp)这个非常著名的第三方库,它实现了HTTP客户端和HTTP服务器的功能,对异步操作提供了非常好的支持,有兴趣可以阅读它的[官方文档](https://aiohttp.readthedocs.io/en/stable/)
### 实例 - 多线程爬取“手机搜狐网”所有页面。 ### 实例 - 多线程爬取“手机搜狐网”所有页面
下面我们把之间讲的所有知识结合起来,用面向对象的方式实现一个爬取“手机搜狐网”的多线程爬虫。
```Python ```Python
...@@ -373,7 +375,7 @@ def main(): ...@@ -373,7 +375,7 @@ def main():
spider_thread.start() spider_thread.start()
while redis_client.exists('m_sohu_task') or is_any_alive(spider_threads): while redis_client.exists('m_sohu_task') or is_any_alive(spider_threads):
pass sleep(5)
print('Over!') print('Over!')
......
...@@ -7,6 +7,3 @@ ...@@ -7,6 +7,3 @@
### 使用Selenium ### 使用Selenium
...@@ -200,27 +200,27 @@ ...@@ -200,27 +200,27 @@
### Day41~55 - [Django](./Day41-55) ### Day41~55 - [Django](./Day41-55)
#### Day41 - [Django实战(01) - 快速上手](./Day41-55/Django2实战01.md) #### Day41 - [Django2实战(01) - 快速上手](./Day41-55/Django2实战01.md)
#### Day42 - [Django实战(02) - 深入模型](./Day41-55/Django2实战02.md) #### Day42 - [Django2实战(02) - 深入模型](./Day41-55/Django2实战02.md)
#### Day43 - [Django实战(03) - 视图和模板](./Day41-55/Django2实战03.md) #### Day43 - [Django2实战(03) - 视图和模板](./Day41-55/Django2实战03.md)
#### Day44 - [Django实战(04) - 表单的应用](./Day41-55/Django2实战04.md) #### Day44 - [Django2实战(04) - 表单的应用](./Day41-55/Django2实战04.md)
#### Day45 - [Django实战(05) - Cookie和会话](./Day41-55/Django2实战05.md) #### Day45 - [Django2实战(05) - Cookie和会话](./Day41-55/Django2实战05.md)
#### Day46 - [Django实战(06) - 日志和缓存](./Day41-55/Django2实战06.md) #### Day46 - [Django2实战(06) - 日志和缓存](./Day41-55/Django2实战06.md)
#### Day47 - [Django实战(07) - 文件上传和通用视图](./Day41-55/Django2实战07.md) #### Day47 - [Django2实战(07) - 文件上传和通用视图](./Day41-55/Django2实战07.md)
#### Day48 - [Django实战(08) - 用户/角色/权限和中间件](./Day41-55/Django2实战08.md) #### Day48 - [Django2实战(08) - 用户/角色/权限和中间件](./Day41-55/Django2实战08.md)
#### Day49 - [Django实战(09) - RESTful架构和应用(上)](./Day41-55/Django2实战09.md) #### Day49 - [Django2实战(09) - RESTful架构和应用(上)](./Day41-55/Django2实战09.md)
#### Day50 - [Django实战(10) - RESTful架构和应用(下)](./Day41-55/Django2实战10.md) #### Day50 - [Django2实战(10) - RESTful架构和应用(下)](./Day41-55/Django2实战10.md)
#### Day51-55 - [Django项目实战](./Day41-55/Django2项目实战.md) #### Day51-55 - [Django2项目实战](./Day41-55/Django2项目实战.md)
- 项目开发流程和相关工具 - 项目开发流程和相关工具
- 生成非HTML内容 - 生成非HTML内容
...@@ -268,9 +268,39 @@ ...@@ -268,9 +268,39 @@
### Day76~90 - [数据处理和机器学习](./Day76-90) ### Day76~90 - [数据处理和机器学习](./Day76-90)
#### Pandas的应用
#### NumPy和SciPy的应用
#### Matplotlib和数据可视化
#### K最邻近分类算法(KNN)
#### 线性回归和Logistic回归
#### 支持向量机(SVM)和Kmeans聚类
#### 决策树和贝叶斯分类
#### Tensorflow实战01
#### Tensorflow实战02
#### Tensorflow实战03
### Day91~100 - [团队项目开发](./Day91-100) ### Day91~100 - [团队项目开发](./Day91-100)
#### 软件项目的过程模型
#### 团队开发工具
#### 模块分割设计与单元测试
#### 用Jenkins实现持续集成
#### 部署和自动化部署
#### 性能测试和改善
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册