urllib模块的使用

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: urllib模块的使用

在python2中有urllib和urllib2两个库来实现发送请求,而在python3中,将这两个库统一为一个urllib库了。


主要分为一下四个功能模块:


requests (请求)

error (异常处理)

parse (url解析)

robotparser(识别robots.txt文件【告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎的漫游器获取的,哪些是可以被漫游器获取的】)

1. urllib.request

请求方法一共有8种,包括: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TARCE。而我们写爬虫常用到的就是get请求和post请求,get请求就是不需要往服务器上传数据的请求,而post请求就需要上传数据,如用户登录,用户注册这些都是post请求


urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

url可以是字符串,也可以是自己构造的Request对象


data是需要发送给服务器的数据对象,如果没有则不用填写,默认为None


timeout超时设置,是一个可选参数,传入超时时间后,如果在指定的时间内服务器没有响应则抛出time out异常


cafile和capath代表 CA 证书和 CA 证书的路径。如果使用HTTPS则可能需要用到


context参数必须是ssl.SSLContext类型,用来指定SSL设置


该函数返回的对象提供的方法有:


read() ,readline() ,readlines() ,fileno(),close() ,这些函数是对HTTP response类型的数据进行操作


info(),返回HTTP message对象,表示远程服务器返回的头信息


getcode(),返回HTTP状态码


geturl(),返回请求的url


status,返回状态码


getheaders(),响应的头部信息


getheader(“Server”),返回响应头指定的参数Server的值

from urllib import request
response = request.urlopen('http://www.baidu.com') # get方式请求
print(response.read().decode('utf-8'))  # 返回的数据格式为bytes类型,需要decode()解码,转换成str类型

构造Request


urlopen()可以支撑我们的一些简单的请求,但是请记住,一个没有请求头的爬虫是没有灵魂的。虽然不使用请求头也可以访问一些网页,但是这样的行为是直接告诉服务器“我是一个爬虫”,那么服务器可能就会拒绝程序的请求,因此我们需要进行伪装,这时候我们就需要去构造我们的HTTP请求体,一个Request对象。比如上面的代码,我们可以这样改写:

from urllib import request 
request = request.Request("http://www.baidu.com")
response = request.urlopen(request)
print(response.read())

运行结果是完全一样的,只不过中间多了一个request对象,推荐大家这么写,因为在构建请求时还需要加入好多内容,通过构建一个request,[服务器]响应请求得到应答,这样显得逻辑上清晰明确。


POST方式


前面我们说的data就是post请求需要传送的数据

from urllib import request, parse
login_url = "http://www.xbiquge.la/login.php?jumpurl=http://www.xbiquge.la/"
dic = {
    "LoginForm[username]": "spider",
    "LoginForm[password]": "123456",
}
data = parse.urlencode(dic)
# 不自己构造Request
response = request.urlopen(login_url, data.encode()) # 注意传入data必须是字节类型
print(response.getcode())
# 自己构造Request
Reqeust = request.Request(login_url, data)
response = request.urlopen(Request)
print(response.getcode())

这里的parse.urlencode就是将数据dic进行URL编码


在某些时候,POST请求是可以使用GET请求的,因为将表单数据添加到URL上的


设置代理(proxy)


有的服务器会根据ip检测用户的访问频度,发现不对劲就把你的ip封了,你就在也访问不了了。这是就需要使用代理ip了,每个一段时间跟换一个ip,服务器就发现不了你在搞蛋。

595dd56552afad3dc282d7765ec6fdd3.png



import urllib.request
proxy_support = urllib.request.ProxyHandler({'https': '58.253.155.101:9999'}) 
opener = urllib.request.build_opener(proxy_support)
# 方式一
urllib.request.install_opener(opener) 
a = urllib.request.urlopen("http://www.baidu.com").read().decode("utf8")
# 方式二
# a = opener.open("http://www.baidu.com").read().decode("utf8")
print(a)

设置请求头headers


User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求


**Referer **: 该网页来自哪页面,服务器在检查反盗链是会判断


Cookie : 保存用户信息,我们在绕过登录时常用到


Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析。


application/[xml] : 在 XML RPC,如 RESTful/SOAP 调用时使用


application/json : 在 JSON RPC 调用时使用


application/x-www-form-urlencoded : 浏览器提交 Web 表单时使用


有的服务器会检测请求的cookie,user-agent等等信息,这时我们就需要将这些信息添加到headers里一起发送给服务器,而这些请求头信息就需要我们在浏览器复制过来。这个user-agent一般都是需要加上的


右键选择“检查”(也可按F12),进入开发者页面


5697cae7c7f4c1372af619e8be977859.png


悬着Network这一栏,在刷新该网站


9d380c26e850a32cf93bbf462063c83d.png


f50b34034f5c8aaaaa5d2ee4dbf43be6.png


代码部分:

from urllib import request
url = "http://www.baidu.com"
headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
}
req = request.Request(url=url, headers=headers)
response = request.urlopen(req)
print(response.read().decode())

2. urllib.error

请求异常主要有两类:URLError和HTTPError


URLError


该异常主要原因有:没有网络,服务器连接失败,找不到指定的服务器等等。我们可以用try except来捕获相应的异常

from urllib import request
from urllib import error
url = "https://www.xgrang23234234.com"
try:
    res = request.urlopen(url)
    print(res.read().decode())
except error.URLError as err:
    print(err)

HTTPError


该异常是URLerror的子类(我们在捕获异常时需要将父类的异常写在子类的异常后面 ),我们发出一个请求时,服务器上都会对应一个 response应答对象,其中它包含一个数字"响应状态码"。


如果 urlopen 或 opener.open 不能处理的,会产生一个 HTTPError,对应相应的状态码,HTTP 状态码表示 HTTP 协议所返回的响应的状态。


注意,urllib 可以为我们处理重定向的页面(也就是 3 开头的响应码),100-299 范围的号码表示成功,所以我们只能看到 400-599 的错误号码。

from urllib import request
from urllib import error
url1 = "https://www.xgrang.com/1/index.index" # 会造成HTTPError的异常
url2 = "https://www.xgrang5435356.com" #会造成URLError的异常
try:
    res = request.urlopen(url1)
    print(res.read().decode())
except error.HTTPError as err: #父类在后,子类在前的原则
    print("发生了一个HTTPError的异常:")
    print(err)
except error.URLError as err:
    print("发生了一个URLError的异常:")
    print(err)

3. urllib.parse

python中的url提供了很多解析和组建URL的函数


urlparse() , 可以将 URL 解析成 ParseResult 对象。对象中包含了六个元素,分别为:


协议(scheme)

域名(netloc)

路径(path)

路径参数(params)

查询路径(query)

片段(fragment)

from urllib import parse
url = "http://user:pwd@domain:80/path1;params1/path2;params2?query=queryarg#fragment"
url_parse = parse.urlparse(url)
print(url_parse.scheme)
print(url_parse.netloc)

urlsplit() , 该函数与前一个函数不同的是不会将路径参数(params)从路径(path)分离出来。当出现多个路径参数是urlparse()会出现问题

from urllib import parse
url = "http://user:pwd@domain:80/path1;params1/path2;params2?query=queryarg#fragment"
url_parse = parse.urlparse(url)
print(url_parse.params) # params2
print(url_parse.path)   # /path1;params1/path2
url_parse2 = parse.urlsplit(url)
print(url_parse2.path)   # /path1;params1/path2;params2
# 很明显urlparse在解析具有多个路径参数是会出错

urlunparse()接收一个列表的参数,而且列表的长度是有要求的,是必须六个参数以上,否则抛出异常。

from urllib.parse import urlunparse
url_compos = ('http', 'user:pwd@domain:80', '/path1;params1/path2', 'params2', 'query=queryarg', 'fragment')
print(urlunparse(url_compos))

urljoin()将两个字符串拼接成url


from urllib.parse import urljoin
# 连接两个参数的url, 将第二个参数中缺的部分用第一个参数的补齐,如果第二个有完整的路径,则以第二个为主
print(urljoin('https://movie.douban.com/', 'index'))
print(urljoin('https://movie.douban.com/', 'https://accounts.douban.com/login'))

urlencode() 函数可以将一个 dict 转换成合法的查询参数,除一些字符以原字符表示外,其他的都会进行URL编码来表示。

from urllib.parse import urlencode
query_args = {
    'username': 'python你好',
    'password': '123456'
}
query_args = urlencode(query_args)
print(query_args) # username=python%E4%BD%A0%E5%A5%BD&password=123456

quote()对特殊字符进行URL编码,unquote()则相反。所以我们可以用这个来实现urlencode的效果

from urllib.parse import quote, unquote
string = "你好"
q_string = quote(string)
uq_string = unquote(q_string)
print(q_string)  # %E4%BD%A0%E5%A5%BD
print(uq_string) # 你好

其他

使用Cookie


一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的机器上。如果使用浏览器访问 Web, 会看到所有保存在硬盘上的 Cookie。在这个文件夹里每一个文件都是一个由“键/值”对组成的文本文件,另外还有一个文件保存有所有对应的 Web 站点的信息


当客户端再次访问这个 Web 站点时这些信息可供该站点使用。由于“Cookie”具有可以保存在本地客户端上的神奇特性, 因此它可以帮助我们实现记录用户个人信息的功能


我们可以通过使用cookie避免一些不要登录认证或者来完善的伪装我们的爬虫


而管理cookie我们需要借助http.cookiejar库中的CookieJar,CookieJar类管理HTTP cookie值、存储HTTP请求生成的cookie、向传出的HTTP请求添加cookie的对象。整个cookie都存储在内存中,对CookieJar实例进行垃圾回收后cookie也将丢失。


该库使用CookieJar的步骤


创建CookieJar 对象或其子类的对象,负责处理cookie

以 CookieJar 对象为参数,创建 urllib.request.HTTPCookieProcessor 对象,该对象负责调用 CookieJar 来管理 cookie

以 HTTPCookieProcessor 对象为参数,调用 urllib.request.build_opener() 函数创建 OpenerDirector 对象

使用 OpenerDirector 对象来发送请求,该对象将会通过 HTTPCookieProcessor 调用 CookieJar 来管理 cookie

# 使用cookie登录人人网
import urllib.request
import http.cookiejar
def spider(url, cookie):
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
        "cookie": cookie
    }
    request = urllib.request.Request(url, headers=headers)
    cookie = http.cookiejar.CookieJar()
    handler = urllib.request.HTTPCookieProcessor(cookie)
    opener = urllib.request.build_opener(handler)
    response = opener.open(request)
    print(response.read().decode("utf8"))
if __name__ == '__main__':
    url = "http://www.renren.com/"
    cookie = "111" #假cookie
    # cookie = "anonymid=kkg86whm-yk1bg4; depovince=GW; _r01_=1; taihe_bi_sdk_uid=c533a95f05616fb08f75377d3930ddce; _de=46FEFF8EAAD410B79011D95327F36536; __utma=151146938.1023465658.1611800234.1611800234.1611800234.1; __utmz=151146938.1611800234.1.1.utmcsr=renren.com|utmccn=(referral)|utmcmd=referral|utmcct=/; taihe_bi_sdk_session=2ee77ba5e0cbfabf28c21913cf66b58a; ick_login=069126e8-fb87-426c-bb9c-75c4f195c9a7; t=0a3e28f5f6c7b27379c00cccd65969820; societyguester=0a3e28f5f6c7b27379c00cccd65969820; id=975870750; xnsid=b3b06863; ver=7.0; loginfrom=null; wpsid=15896663617555; wp_fold=0; jebecookies=47e35a5a-8034-4680-bac2-3d63bdf289c6|||||" # 真cookie
    spider(url, cookie)

自动发送B站评论


# 发送b站弹幕
import urllib.request
import http.cookiejar
import urllib.parse
def spider(Id, Message):
    url = "https://api.bilibili.com/x/v2/reply/add"
    data = {
        "oid": Id,  # 你要发送的视频id
        "type": "1",
        "message": Message,  # 你要发送到消息
        "plat": "1",
        "ordering": "heat",
        "jsonp": "jsonp",
        "csrf": "44e011475a96e0d86c7ccad207f03508",
    }
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
        "cookie": "cookie" # 复制自己浏览器的cookie
    }
    data = urllib.parse.urlencode(data)
    request = urllib.request.Request(url=url, data=data.encode('utf8'), headers=headers)
    cookie = http.cookiejar.CookieJar()
    handler = urllib.request.HTTPCookieProcessor(cookie)
    opener = urllib.request.build_opener(handler)
    response = opener.open(request)
    print(response.read().decode())
if __name__ == '__main__':
    spider(Id="801326692", Message="阿七回来了!")


参考来源

https://www.cnblogs.com/-wenli/p/10894562.html

https://pujichun.gitee.io/2020/03/01/urllib%E5%BA%93%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/

https://blog.csdn.net/qq_29983883/article/details/105492143


目录
相关文章
|
1月前
|
数据采集 JSON 应用服务中间件
urllib与requests模块万字超详细!!
本文介绍了Python中用于发送网络请求的两个重要模块:`urllib` 和 `requests`。首先,文章详细讲解了 `urllib` 模块的基本使用方法,包括构造请求、发送请求、处理响应等。接着,文章重点介绍了 `requests` 模块,强调了其在企业中的广泛应用,以及如何发送GET和POST请求、处理响应、使用代理、处理Cookie等内容。最后,文章还探讨了 `requests` 模块的高级功能,如处理证书错误、设置超时、使用 `retrying` 模块等,帮助读者全面掌握网络请求的处理技巧。
58 4
|
7月前
|
安全 测试技术 API
urllib3库的介绍以及使用
`urllib3`是Python的HTTP库,支持HTTP/HTTPS,自动管理连接池,提供代理、证书配置,重定向处理等功能。其优势在于连接池管理和HTTPS支持。要安装,使用`pip install urllib3`。发起HTTP请求如`http.request('GET', 'http//example.com')`。处理响应包括状态码、头部和内容。高级功能包括连接池管理、超时和重试策略。注意线程安全、资源释放及错误处理。官方文档和相关文章可提供更多信息。
212 0
|
编解码 Python
urllib库(中)
urllib库(中)
56 0
|
应用服务中间件 nginx Python
|
数据采集 Python
爬虫第一次笔记 urllib的基本使用 urllib一个类型,六个方法 urllib下载 urllib请求对象的定制
爬虫第一次笔记 urllib的基本使用 urllib一个类型,六个方法 urllib下载 urllib请求对象的定制
131 0
爬虫第一次笔记 urllib的基本使用 urllib一个类型,六个方法 urllib下载 urllib请求对象的定制
|
数据采集 JSON 数据格式
python爬虫urllib3模块详解
python爬虫urllib3模块详解
535 1
python爬虫urllib3模块详解
|
数据采集 数据安全/隐私保护 Python
Python:urllib2模块Handler处理器 和 自定义Opener(一)
Python:urllib2模块Handler处理器 和 自定义Opener(一)
184 0
Python:urllib2模块Handler处理器 和 自定义Opener(一)
|
存储 数据采集 JavaScript
Python:urllib2模块Handler处理器 和 自定义Opener(二)
Python:urllib2模块Handler处理器 和 自定义Opener(二)
238 0
Python:urllib2模块Handler处理器 和 自定义Opener(二)
|
数据采集 JSON 网络安全
python爬虫urllib模块详解
python爬虫urllib模块详解
319 0
python爬虫urllib模块详解
|
Python
Python:urllib2模块GET和POST请求
Python:urllib2模块GET和POST请求
367 0

热门文章

最新文章