01_Urllib库

所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。 在Python中有很多库可以用来抓取网页,我们先使用urllib

什么是Urllib

Python内置的HTTP请求库
urllib.request 请求模块
urllib.error 异常处理理模块
urllib.parse url解析模块
urllib.robotparser robots.txt解析模块

import urllib.request
# 向指定的url地址发送请求,并返回服务器响应的类文件对象
response = urllib.request.urlopen("http://www.baidu.com/")
# 服务器返回的类文件对象支持Python文件对象的操作方法
# read()方法就是读取文件里的全部内容,返回字符串
html = response.read().decode('utf-8')
# 打印响应内容
print(html)

分析代码:

import urllib.request

就是将urllib.request引入进来

response = urllib.request.urlopen("http://www.baidu.com/")

调用urlopen方法,传入的url网址是百度首页,urlopen(url,data=None,timeout=数)。
第⼀个参数 URL是必须要传送的,可以传⼊⼀个字符串类型的 url地址,同时打开这个 url 并返回⼀个像⽂件对象⼀样的对象
第⼆个参数是data是经过编码的post数据(⼀般使⽤urllib.urlencode()来编码,我们后⾯会说到),默认为空None
第三个参数是timeout是可选的超时期(以秒为单位),供所有阻塞操作内部使⽤。默认为60s,也可以直接设置timeout=10

html = response.read().decode('utf-8')

urlopen()返回的⽂件对象,除了⽀持⽂件⽅法外,还⽀持下⾯的这些常⽤的⽅法:

  • response.getcode() 返回整数形式的HTTP响应代码,⽐如成功返回 200,未找到⽂件时返回 404
  • response.geturl() 返回所返回的数据的实际url,但是会考虑发⽣的重定向问题
  • response.info() 返回映射对象,该对象带有与url关联的信息, 对 HTTP来说,返回的服务器响应包含HTTP报头

Request

import urllib.request
request=urllib.request.Request("http://www.baidu.com")
response=urllib.request.urlopen(request)
html=reponse.read().decode("utf-8")
print(html)

运行结果与上面一样
在我们第⼀个例⼦⾥,urlopen()的url参数就是⼀个 url地址
但是如果需要执⾏更复杂的操作,⽐如增加 HTTP报头,可以创建⼀个 、Request 实例来作为urlopen()的 url参数,⽽url地址则作为 Request实例的参数。

import urllib.request

ua_headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"
}
# 通过urllib.request.Request() 方法构造一个请求对象
request = urllib.request.Request("http://www.baidu.com/", headers = ua_headers)

# 向指定的url地址发送请求,并返回服务器响应的类文件对象
response = urllib.request.urlopen(request)

----------------------------------------------
ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) ' \
     'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77' \
     ' Safari/537.36'
# 添加自定义的头信息
req = urllib.request.Request('http://httpbin.org/user-agent')
req.add_header('User-Agent', ua)

新建 Request实例,url为url字符串,data是伴随url提交的数据(⽐如要post的数据),headers是⼀个字典,包含了可表示 HTTP报头的键值对。
注意,data请求为空时,默认 HTTP请求为"GET",提供 data参数时, HTTP请求将从"GET"改为‘POST’
在这里插入图片描述
headers的⼀些属性,需要特别注意⼀下:

  • User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器 发出的请求;
  • Content-Type : ⽤来确定 HTTP Body 中的内容该怎样解析,服务器会检查该值,设置错误会导致服务器拒绝服务
  • application/xml : 在 XML RPC 调⽤时使⽤
  • application/json : 在 JSON RPC 调⽤时使⽤
  • application/x-www-form-urlencoded : 浏览器提交 Web 表单时使⽤

Get方式

GET请求⼀般⽤于我们向服务器获取数据,比如说,我们⽤百度搜索新闻:
https://www.baidu.com/s?wd=新闻
在这里插入图片描述在其中我们可以看到在 http://www.baidu.com/s? 之后出现⼀个⻓⻓的字符 串,其中就包含我们要查询的关键词。

import urllib #负责 url 编码处理 
import urllib.request
url = "http://www.baidu.com/s" 
word = {"wd":"新闻"} 
word = urllib.urlencode(word)#转换成 url 编码格式(字符串) 
newurl = url + "?" + word # url⾸个分隔符就是 ?
headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) Apple WebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.3 6"} 
request=urllib.request.Request(url,headers=headers)
response=urllib.request.urlopen(request)
html=response.read().decode("htf-8") 

⼀般 HTTP请求提交 HTML表单数据,word 需要编码成 URL 编码格式,然后做为参数传到Request对象。

编码⼯作使⽤urllib的 urlencode() 函数,帮我们将 key:value 这 样的键值对转换成 “key=value” 这样的字符串,解码⼯作可以使⽤ urllib的 unquote() 函数

urllib.parse.quote/unquote
中文String串编码转换

import urllib
word={"wd":"新闻"}
# 将字典按 URL 编码转换,汉字部分先转成 GBK 编码,然后把  \x 替换成  % 
urllib.urlencode(word)
"wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2" 
# 把  % 替换成  \x,变回  GBK 编码,打印出来 
print (urllib.unquote("wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE% A2"))
wd="新闻"

Post方式

上⾯我们说了 Request请求对象的⾥有 data参数,它就是⽤在 POST⾥的, 我 们要传送的数据就是这个参数 data,data是⼀个字典,⾥⾯要匹配键值对。

import urllib.request,parse
# 导入json包,负责处理json格式的模块
import json

'''
大致流程:
1.利用data构造内容,然后urlopen打开
2.返回一个json格式的结果
3.结果就应该是服务器返回的释义
'''

baseurl = 'http://fanyi.baidu.com/sug'
# 存放用来模拟form的数据,一定是dict格式
keyword = input("请输入需要翻译的内容:")
data = {
    'kw': keyword
}
# print(data)

# 需要使用parse模块对data进行编码
data = parse.urlencode(data)
data = data.encode('utf-8')
# print("编码后的data:",data)
# print("编码后的data类型:",type(data))
# 当需要类型为bytes时:在数据的后面加上: data = data.encode('utf-8')

# 构造请求头,请求头部至少包含:
# 1.传入数据的长度
# 2.request要求传入的请求是一个dict格式

# 有了headers,data,url就可以尝试发出请求
rsp = urllib.request.urlopen(baseurl,data=data)

json_data = rsp.read().decode("utf-8","ignore")

# 把json字符串转换为字典
json_data = json.loads(json_data)
# print(json_data)

for item in json_data['data']:
    if item['k'] == keyword:
        print(item['k'], ": ", item['v'])

# 使用Request
import urllib.request,parse
import json

baseurl = 'http://fanyi.baidu.com/sug'
keyword = input("请输入需要翻译的内容:")
data = {
    'kw': keyword
}

# 需要使用parse模块对data进行编码
data = parse.urlencode(data)
data = data.encode('utf-8')

header = {
    'Content-Length':len(data)
}
# 构造Request实例
req = urllib.request.Request(url=baseurl,data=data,headers=header)

# 发出请求
rsp = request.urlopen(req)

json_data = rsp.read().decode("utf-8","ignore")

# 把json字符串转换为字典
json_data = json.loads(json_data)

for item in json_data['data']:
    # if item['k'] == keyword:
        print(item['k'], ": ", item['v'])

urlretrieve

用于下载东西
urllib.request.urlretrieve(url,目的地址)

URLError

在我们⽤urlopen⽅法发出⼀个请求时,如果 urlopen不能处理这个 response,就产⽣urlError。这⾥主要说的是 URLError和 HTTPError,以及对 它们的错误处理
URLError 产⽣的原因可能有:

  1. 没有⽹络连接
  2. 服务器连接失败
  3. 找不到指定的服务器
    我们可以⽤ try except 语句来捕获相应的异常。下⾯的例⼦⾥我们访问了 ⼀个不存在的域名:
import urllib.request
try:
	request=urllib.request.urlopen("http://www.aaadddffsfr.com").read().decode("utf-8")
except urllib.request.URLErrop as err:
print(err)

HTTPError

HTTPError 是 URLError 的⼦类,通常在特定 HTTP URLs(⼦URL)中产⽣。 我 们利⽤urlopen⽅法发出⼀个请求时,服务器上都会对应⼀个 response应 答对 象,其中它包含⼀个数字"响应状态码"。
如果不能处理的,urlopen 会产⽣⼀个HTTPError,对应相应的状态吗, HTTP 状态码表示 HTTP 协议所返回的响应的状态。

import urllib.request
try:
	request=urllib.request.Request("http:www.adawfsr.com").read()
except urllib.request.HTTPError as err:
print(err.code)
print(err)

404
HTTP Error 404: Not Found

响应状态码

1xx:信息

100 Continue 服务器仅接收到部分请求,但是⼀旦服务器并没有拒绝该请求,客 户端应该继续发送 其余的请求。
101 Switching Protocols 服务器转换协议:服务器将遵从客户的请求转换到另外⼀种协议。

2xx:成功
200 OK 请求成功(其后是对 GET 和 POST 请求的应答⽂档。)
201 Created 请求被创建完成,同时新的资源被创建。
202 Accepted 供处理的请求已被接受,但是处理未完成。
203 Non-authoritative Information ⽂档已经正常地返回,但⼀些应答头可能不正确,因为使⽤的是⽂档的拷⻉。
204 No Content 没有新⽂档。浏览器应该继续显示原来的⽂档。如果⽤户定期地 刷新⻚⾯,⽽Servl et 可以确定⽤户⽂档⾜够新,这个状态代码是很有⽤的。 205 Reset Content 没有新⽂档。但浏览器应该重置它所显示的内容。⽤来强制浏览器清除表单输⼊内容 。
206 Partial Content 客户发送了⼀个带有 Range 头的 GET 请求,服务器完成了它

3xx:重定向
300 Multiple Choices 多重选择。链接列表。⽤户可以选择某链接到达⽬的地。最多允许五个地址。
301 Moved Permanently 所请求的⻚⾯已经转移⾄新的 url。
302 Found 所请求的⻚⾯已经临时转移⾄新的 url。
303 See Other 所请求的⻚⾯可在别的 url 下被找到。
304 Not Modified 未按预期修改⽂档。客户端有缓冲的⽂档并发出了⼀个条件性 的请求(⼀般是提供 I f-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:服务器错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值