模块的使用"/>
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('') # get方式请求 print(response.read().decode('utf-8')) # 返回的数据格式为bytes类型,需要decode()解码,转换成str类型
-
-
构造Request
urlopen()可以支撑我们的一些简单的请求,但是请记住,一个没有请求头的爬虫是没有灵魂的。虽然不使用请求头也可以访问一些网页,但是这样的行为是直接告诉服务器“我是一个爬虫”,那么服务器可能就会拒绝程序的请求,因此我们需要进行伪装,这时候我们就需要去构造我们的HTTP请求体,一个Request对象。比如上面的代码,我们可以这样改写:
from urllib import request request = request.Request("") response = request.urlopen(request) print(response.read())
运行结果是完全一样的,只不过中间多了一个request对象,推荐大家这么写,因为在构建请求时还需要加入好多内容,通过构建一个request,[服务器]响应请求得到应答,这样显得逻辑上清晰明确。
-
POST方式
前面我们说的data就是post请求需要传送的数据
from urllib import request, parselogin_url = ".php?jumpurl=/" 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,服务器就发现不了你在搞蛋。
import urllib.requestproxy_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("").read().decode("utf8") # 方式二 # a = opener.open("").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),进入开发者页面
-
悬着Network这一栏,在刷新该网站
代码部分:
from urllib import requesturl = "" 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 errorurl = "" 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 errorurl1 = ".index" # 会造成HTTPError的异常 url2 = "" #会造成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 parseurl = "http://user:pwd@domain:80/path1;params1/path2;params2?query=queryarg#fragment" url_parse = parse.urlparse(url) print(url_parse.scheme) print(url_parseloc)
-
urlsplit() , 该函数与前一个函数不同的是不会将路径参数(params)从路径(path)分离出来。当出现多个路径参数是urlparse()会出现问题
from urllib import parseurl = "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/path2url_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('/', 'index')) print(urljoin('/', ''))
-
urlencode() 函数可以将一个 dict 转换成合法的查询参数,除一些字符以原字符表示外,其他的都会进行URL编码来表示。
from urllib.parse import urlencodequery_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.cookiejardef 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 = "/"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|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|||||" # 真cookiespider(url, cookie)
-
自动发送B站评论
# 发送b站弹幕import urllib.request import http.cookiejar import urllib.parsedef spider(Id, Message):url = ""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="阿七回来了!")
参考来源
- .html
- /
更多推荐
urllib模块的使用
发布评论