爬虫入门之urllib库(一)
1 爬虫概述
(1)互联网爬虫
一个程序,根据Url进行爬取网页,获取有用信息
(2)核心任务
爬取网页
解析数据
难点 :爬虫和反爬虫之间的博弈
(3)爬虫语言
php 多进程和多线程支持不好
java 目前java爬虫需求岗位旺盛,但代码臃肿,重构成本高,而爬虫需要经常修改,所以不好用
C\C++ 学习成本比较高,性能和效率高,停留在研究层面,市场需求量小。体现程序员能力。
python 语法简洁优美、对新手友好学习成本低、支持的模块非常多、有scrapy非常强大的爬虫框架
(4)爬虫分类
#通用爬虫
实例 百度、360、google、sougou等搜索引擎, 将网上的数据进行爬取并进行排名展示
功能 访问网页->抓取数据->数据存储->数据处理->提供检索服务
抓取流程
1. 给定一些起始的URL,放入待爬取队列
2. 从队列中获取url对象,开始爬取数据
3. 分析网页,获取网页内的所有url,入队,继续重复执行第二步
搜索引擎如何获取新网站链接
1. 主动给搜索引擎提交url
2. 在其他网站中设置友情链接
3. 百度和DNS服务商合作,只要有域名,就会收录新网站
robots协议
1.一个约定俗成的协议,添加robots.txt文件,来说明本网站哪些内容不可以被抓取,起到限制作用
2.自己写的爬虫无需遵守
网站排名(SEO)
1. 根据pagerank值进行排名(参考个网站流量、点击率等指标)
2. 百度竞价排名,钱多就是爸爸
缺点:
1. 抓取的数据大多是无用的
2.不能根据用户的需求来精准获取数据
#聚焦爬虫
功能
根据需求,实现爬虫程序,抓取需要的数据
原理
1.网页都有自己唯一的url(统一资源定位符)
2.网页都是html组成
3.传输协议都是http/https
设计思路
1.确定要爬取的url
2.模拟浏览器通过http协议访问url,获取服务器返回的html代码
3.解析html字符串(根据一定规则提取需要的数据)
# URL放入爬取队列原因: 很多网页都有友情链接,如果爬虫漫无目的的爬取数据会爬到其他网站,不同的网站都会存在不同的外部链接,所以有可能会重复,从队列中获取可以避免重复网址的爬取
(5)整体框架
1.python语法
2.使用的python库
urllib.request
urllib.parse
requests
scrapy
3.解析内容方式:
正则表达式
xpath 推荐使用xpath
bs4
jsonpath
4.采集动态html(一般模拟浏览器):因为所有的网站都不止存在一个请求(js.csss等动态请求),如果仅仅对网站首页 发送请求,会导致网站内容接受不全 selenium + phantomjs
5.scrapy
高性能异步网络爬虫框架
6.分布式爬虫
scrapy-redis组件
7.反爬虫的一般手段
User-Agent 通过请求头传递给服务器,用以说明访问数据浏览器信息反爬虫:先检查是否有UA,或UA是否合法
代理IP : 西刺代理
验证码访问 : 打码平台
动态加载网页
数据加密 : 分析js代码
爬虫-反爬虫-反反爬虫
2 http协议
(1)常见端口
http 明文传输,端口号80
https 加密传输,端口号443
常见服务器端口号
ftp 21
ssh 22
mysql 3306
MongoDB 27017
redis 6379
(2) http工作原理
url组成 协议 主机HOST 端口号 资源路径 query-string参数 锚点
url: http://www.baidu.com:80/index.html?username=dancer&password=123456#anchor
上网原理 : 一个网页一般都不止有一个url请求,在网页内.js\.css文件也都可以是请求。当所有的请求都下载完成后,浏览器会把css.js.img等都翻译成图文并茂的形式
#请求头详解
Accept
Accept-Encoding
Accept-Language
Cache-Control 缓存控制
Connection
Cookie
Host
Upgrade-Insecure-Requests 是否升级为https协议
User-Agent 用户代理
X-Requested-With ajax请求
#响应头详解
Connection
Content-Encoding gzip 压缩格式,浏览器需要对其进行解压缩,我们自己写的爬虫,不要写这个
Content-Type 服务器向客户端回传数据类型
Date
Expires 过期时间
Server
Transfer-Encoding 内容是否分包传输
(3) http常见的状态码
1
xx:信息
100 Continue
服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。
101 Switching Protocols
服务器转换协议:服务器将遵从客户的请求转换到另外一种协议。
2xx:成功
200 OK
请求成功(其后是对GET和POST请求的应答文档)
201 Created
请求被创建完成,同时新的资源被创建。
202 Accepted
供处理的请求已被接受,但是处理未完成。
203 Non-authoritative Information
文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝。
204 No Content
没有新文档。浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。
205 Reset Content
没有新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。
206 Partial Content
客户发送了一个带有Range头的GET请求,服务器完成了它。
3xx:重定向
300 Multiple Choices
多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。
301 Moved Permanently
所请求的页面已经转移至新的url。
302 Moved Temporarily
所请求的页面已经临时转移至新的url。
303 See Other
所请求的页面可在别的url下被找到。
304 Not Modified
未按预期修改文档。客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
305 Use Proxy
客户请求的文档应该通过Location头所指明的代理服务器提取。
306 Unused
此代码被用于前一版本。目前已不再使用,但是代码依然被保留。
307 Temporary Redirect
被请求的页面已经临时移至新的url。
4xx:客户端错误
400 Bad Request
服务器未能理解请求。
401 Unauthorized
被请求的页面需要用户名和密码。
401.1
登录失败。
401.2
服务器配置导致登录失败。
401.3
由于 ACL 对资源的限制而未获得授权。
401.4
筛选器授权失败。
401.5
ISAPI/CGI 应用程序授权失败。
401.7
访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。
402 Payment Required
此代码尚无法使用。
403 Forbidden
对被请求页面的访问被禁止。
403.1
执行访问被禁止。
403.2
读访问被禁止。
403.3
写访问被禁止。
403.4
要求 SSL。
403.5
要求 SSL 128。
403.6
IP 地址被拒绝。
403.7
要求客户端证书。
403.8
站点访问被拒绝。
403.9
用户数过多。
403.10
配置无效。
403.11
密码更改。
403.12
拒绝访问映射表。
403.13
客户端证书被吊销。
403.14
拒绝目录列表。
403.15
超出客户端访问许可。
403.16
客户端证书不受信任或无效。
403.17
客户端证书已过期或尚未生效。
403.18
在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。
403.19
不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。
403.20
Passport 登录失败。这个错误代码为 IIS 6.0 所专用。
404 Not Found
服务器无法找到被请求的页面。
404.0
没有找到文件或目录。
404.1
无法在所请求的端口上访问 Web 站点。
404.2
Web 服务扩展锁定策略阻止本请求。
404.3
MIME 映射策略阻止本请求。
405 Method Not Allowed
请求中指定的方法不被允许。
406 Not Acceptable
服务器生成的响应无法被客户端所接受。
407 Proxy Authentication Required
用户必须首先使用代理服务器进行验证,这样请求才会被处理。
408 Request Timeout
请求超出了服务器的等待时间。
409 Conflict
由于冲突,请求无法被完成。
410 Gone
被请求的页面不可用。
411 Length Required
"Content-Length" 未被定义。如果无此内容,服务器不会接受请求。
412 Precondition Failed
请求中的前提条件被服务器评估为失败。
413 Request Entity Too Large
由于所请求的实体的太大,服务器不会接受请求。
414 Request-url Too Long
由于url太长,服务器不会接受请求。当post请求被转换为带有很长的查询信息的get请求时,就会发生这种情况。
415 Unsupported Media Type
由于媒介类型不被支持,服务器不会接受请求。
416 Requested Range Not Satisfiable
服务器不能满足客户在请求中指定的Range头。
417 Expectation Failed
执行失败。
423
锁定的错误。
5xx:服务器错误
500 Internal Server Error
请求未完成。服务器遇到不可预知的情况。
500.12
应用程序正忙于在 Web 服务器上重新启动。
500.13
Web 服务器太忙。
500.15
不允许直接请求 Global.asa。
500.16
UNC 授权凭据不正确。这个错误代码为 IIS 6.0 所专用。
500.18
URL 授权存储不能打开。这个错误代码为 IIS 6.0 所专用。
500.100
内部 ASP 错误。
501 Not Implemented
请求未完成。服务器不支持所请求的功能。
502 Bad Gateway
请求未完成。服务器从上游服务器收到一个无效的响应。
502.1
CGI 应用程序超时。 ·
502.2
CGI 应用程序出错。
503 Service Unavailable
请求未完成。服务器临时过载或当机。
504 Gateway Timeout
网关超时。
505 HTTP Version Not Supported
服务器不支持请求中指明的HTTP协议版本
3 抓包工具fiddler
(1) 配置https
点击Tools-->options--->https--->选中面板下
Capture Https CONNECTS
Decrypt Https Traffic
Ignore
复选框后,将Fiddler重启即可
(2) Web Session 面板
主要是Fiddler抓取到的每条http请求(每条称一个session),主要包含了请求的url,协议,状态码,body等信息
(3) 数据统计版
Inspector
ImageView标签: JPG 格式使用 ImageView 就可以看到图片
TextView 标签: HTML/JS/CSS 使用 TextView 可以看到响应的内容。
Raw标签: Raw标签可以查看响应报文和响应正文,但是不包含请求报文
Cookies标签: Cookies标签可以看到请求的cookie和响应的set-cookie头信息。
WebForms: post请求所有表单数据
Headers: 请求头和响应头信息
Json\XML: Json或XML格式的数据
其他面板
Statistics面板 HTTP请求的性能和其他数据分析
composer面板 可以模拟向相应的服务器发送数据的过程
Filters面板 Filter标签则可以设置Fiddler的过滤规则,来达到过滤http请求的目的。最简单如:过滤内网http 请求而只抓取internet的http请求,或则过滤相应域名的http请求。
WebSession选择功能
select json\html\image
cls清除所有请求
?xxx搜索
4 Urllib库
(1)版本
python2
urllib
urllib2
python3
urllib
urllib2 官方文档:https://docs.python.org/2/library/urllib2.html
urllib2 源码:https://hg.python.org/cpython/file/2.7/Lib/urllib2.py
urllib2 在 python3.x 中被改为urllib.request
字节-->字符串 解码decode
字符串-->字节 编码encode
(2)常见的命令
请求响应
urllib.request.urlopen() 返回一个response对象
urllib.request.urlretrieve() 读取内容,直接保存到本地 图片/视频/网页
response.read() 读取二进制数据
response.readline() 读取一行
response.readlines() 读取多行
response.getcode() 获取状态码
response.geturl() 获取请求对象l是由哪个url返回来的
response.getheaders() 获得请求头信息
处理URL
urllib.parse.urlencode() 把字典对象解析成url可识别的参数字符串
#例如
url = 'https://www.baidu.com/s?'
data = {
'wd':'美女'
}
source = urllib.parse.urlencode(data)
url = url+source
print(url)
urllib.parse.quote() url编码中只能出现-_.a~z 如果有中文需要进行编码
#例如
url在线编码工具
http://tool.oschina.net/encode?type=4
url = urllib.pares.quote('http://www.baidu.com/user=语言&pass=123')
urllib.parse.unquote() url解码
构建请求对象
User-Agent定制 urllib.request.Request 可以使用这个类来定制一个请求对象,来模拟浏览器登录
#模拟请求头
headers = {
'User-Agent':'xxxxx'
}
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
print(response.read().decode())