From a97f4ac4e57551c8383a75753241dd1da3d730da Mon Sep 17 00:00:00 2001 From: jackfrued Date: Mon, 28 May 2018 19:44:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E7=88=AC=E8=99=AB?= =?UTF-8?q?=E7=AC=AC1=E5=A4=A9=E7=9A=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...70\345\205\263\345\267\245\345\205\267.md" | 23 ++++++++++++++++++ Day66-75/res/http-request.png | Bin 0 -> 6092 bytes Day66-75/res/http-response.png | Bin 0 -> 6553 bytes 3 files changed, 23 insertions(+) create mode 100644 Day66-75/res/http-request.png create mode 100644 Day66-75/res/http-response.png diff --git "a/Day66-75/01.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md" "b/Day66-75/01.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md" index e4b7fb2..3188562 100644 --- "a/Day66-75/01.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md" +++ "b/Day66-75/01.\347\275\221\347\273\234\347\210\254\350\231\253\345\222\214\347\233\270\345\205\263\345\267\245\345\205\267.md" @@ -89,7 +89,17 @@ Disallow: / #### 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请求(请求行+请求头+空行+[消息体]): + +![](/Users/Hao/Desktop/Python-100-Days/Day41-55/res/http-request.png) + +HTTP响应(响应行+响应头+空行+消息体): + +![](/Users/Hao/Desktop/Python-100-Days/Day41-55/res/http-response.png) + +> 说明:但愿这两张如同泛黄的照片般的截图帮助你大概的了解到HTTP是一个怎样的协议。 #### 相关工具 @@ -148,6 +158,19 @@ Disallow: / 6. robotparser:解析robots.txt的工具 + ```Python + >>> from urllib import robotparser + >>> parser = robotparser.RobotFileParser() + >>> parser.set_url('https://www.taobao.com/robots.txt') + >>> parser.read() + >>> parser.can_fetch('Hellokitty', 'http://www.taobao.com/article') + False + >>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/article') + True + >>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/product') + False + ``` + ### 一个简单的爬虫 构造一个爬虫一般分为数据采集、数据处理和数据存储三个部分的内容。 diff --git a/Day66-75/res/http-request.png b/Day66-75/res/http-request.png new file mode 100644 index 0000000000000000000000000000000000000000..aca9287cdf8821ac8a87b198239cb606a3019562 GIT binary patch literal 6092 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 literal 0 HcmV?d00001 diff --git a/Day66-75/res/http-response.png b/Day66-75/res/http-response.png new file mode 100644 index 0000000000000000000000000000000000000000..f2b8ae3c19ac0140e92d50303c3c66c0541dccc8 GIT binary patch literal 6553 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ʏC^x|zzwi-Rs}wGp=M}Gva~9RT zi%1_lYz3mr&^BSZ6ke$-y9jGprN7;QMPFhUl*w$1u?<0$WOx5c_Pi^Z^EMZZcqp|S z+{!diweu|<}@>|7{BuqK?T}-KHaekXCY7N zShGnK&Bqx%vwD<^kW89!&r6jBLeqa7A^~f-uWhcVnWD4g8tNs>pVL{OHGAqBDOml) z(ch+RJ`UH}-$pAGAumTT`#&IWiDdV}mU4*^{EX?!%u;y+!tzx~fyCFl@Q^0Gs?*V5 z(p1>?%^kl4TwT9C*&7!IPc3+5(sa*x?3Oa(hB@ftyL8$KR*H$Y5 zmJ-7E%44?zfEsl+cG*B}yua+e2JFD#RA)VDjlJ&;MT$VNaG9+l2mKQux>Z_r7w~UH>VjE1vlOL*>fFSHBdB ZLI*@&LkpnJSAQc!50Tocm58Si{{yIUcs2k4 literal 0 HcmV?d00001 -- GitLab