当前位置: 首页 > biancheng >正文

爬虫基础-urllib库的使用

注:本文章为学习过程中对知识点的记录,供自己复习使用,也给大家做个参考,如有错误,麻烦指出,大家共同探讨,互相进步。
借鉴出处:
该文章的路线和主要内容:崔庆才(第2版)python3网络爬虫开发实战
bytes类型:https://blog.csdn.net/apple_50618492/article/details/114677967
python中文官网:https://docs.python.org/zh-cn/3/library/urllib.html#module-urllib

urllib包含4个模块:

  • request:打开和读取url(模拟请求的发送)
  • error:异常处理模块(包含urllib.request抛出的异常)
  • parse:用于解析url,提供了许多url的处理方法(例如拆分、解析、合并等)
  • robotparser:解析robots.txt来判断网站爬取的合法性(用的较少)

1、request模块
request下的方法:
①urlopen()函数:打开统一资源定位符 url,具体API如下:
urllib.request.urlopen(url, data=None, [timeout,]*, cafile=None, capath=None, cadefault=False, context=None)

  • data可选参数。使用改参数时,需要使用bytes方法将参数转化为字节流编码格式的内容,即bytes类型python3新增的字节串类型;str字符串由多个字符组成,以字符为单位进行操作;bytes字符串由多个字节(二进制格式的数据)组成,以字节为单位进行操作,可用于网络上传输数据,也可用于存储各种二进制格式的文件:picture or music and so on
  • timeout可选参数。用于设置超时时间,单位为秒。若果超过设置的时间,请求还没有得到响应,就会抛出异常。如未指定,将使用全局默认超时参数。本参数实际仅对 HTTP、HTTPS 和 FTP 连接有效。
  • (基本很少用,该参数用于实现SSL加密传输)如果给定了 context 参数,则必须是一个 ssl.SSLContext 实例,用于描述各种 SSL 参数。更多详情请参阅 HTTPSConnection 。
  • (基本很少用) cafile 和 capath 为可选参数,用于为 HTTPS 请求指定一组受信 CA 证书。cafile 应指向包含CA 证书的单个文件, capath 则应指向哈希证书文件的目录。更多信息可参阅 ssl.SSLContext.load_verify_locations() 。
  • (已被弃用)参数 cadefault 将被忽略。

输入:

from urllib import request, error, parse
import socket
dict = {'name': 'Jack Chan'}
data = bytes(parse.urlencode(dict), encoding='utf-8')
try:
    # timeout设0.1会进入except,删除timeout或将timeout增大会进入else
    res = request.urlopen('https://www.httpbin.org/post', data=data, timeout=0.1)
except error.URLError as e:
    print(e.reason)
    if isinstance(e.reason, socket.timeout):
        print('Timeout!')
else:
    print(res.read().decode('utf-8'), res.url, res.headers, res.getheaders(), res.getheader('Server'), res.msg, res.version, res.status, res.reason, res.debuglevel, res.closed, sep='\n')

输出:
选择timeout=0.1

timed out
Timeout!

删除timeout或增大timeout

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "name": "Jack Chan"
  },
  "headers": {
    "Accept-Encoding": "identity",
    "Content-Length": "14",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "www.httpbin.org",
    "User-Agent": "Python-urllib/3.9",
    "X-Amzn-Trace-Id": "Root=1-633af480-13ffcba33f81071c21cfc8b5"
  },
  "json": null,
  "origin": "120.227.32.26",
  "url": "https://www.httpbin.org/post"
}

https://www.httpbin.org/post
Date: Mon, 03 Oct 2022 15:00:52 GMT
Content-Type: application/json
Content-Length: 461
Connection: close
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

[('Date', 'Mon, 03 Oct 2022 14:41:04 GMT'), ('Content-Type', 'application/json'), ('Content-Length', '461'), ('Connection', 'close'), ('Server', 'gunicorn/19.9.0'), ('Access-Control-Allow-Origin', '*'), ('Access-Control-Allow-Creden
tials', 'true')]
gunicorn/19.9.0
OK
11
200
OK
0
False

本函数总会返回一个HTTPResponse类型的对象,带有
常用属性:
url(已读取资源的 URL,通常用于确定是否进行了重定向。3.9 版后已移除: geturl()已弃用,建议改用 url。)
msg
version(获取HTTP协议版本号(10 for HTTP/1.0, 11 for HTTP/1.1))、
status(3.9 版后已移除: code、getstatus()已弃用,建议改用 status。)
reason
debuglevel(0关闭调试 模式、1开启调试模式)、
closed
常用方法:
read
getheaders(3.9 版后已移除: info()已弃用。也可以使用headers,不过两者返回的数据类型不一样,根据需求使用)
getheader

②Request():因为urlopen方法不能在请求中加入Headers等信息,所以引入了Request类
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

  • url:请求url,这个是必传参数,其他都是可选参数。
  • data:必须传bytes类型。
  • headers:字典类型,可通过headers参数直接构造,也可以通过add_header方法添加
  • origin_req_host:请求目标的host名称或ip地址
  • unverifiable:默认False。如果设为True,表示没有足够的权限来接收这个请求的结果。
  • method:GET、POST、PUT等

输入:

from urllib import request, error, parse
url = 'https://www.httpbin.org/post'
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0',
    'Host':'www.httpbin.org'
}
dict = {'name': 'Jack Chan'}
data = bytes(parse.urlencode(dict), encoding='utf-8')
try:
    req = request.Request(url=url, data=data, headers=headers, method='POST')
    res = request.urlopen(req)
except error.URLError as e:
    print(e.reason)
else:
    print(res.read().decode('utf-8'))

输出:

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "name": "Jack Chan"
  },
  "headers": {
    "Accept-Encoding": "identity",
    "Content-Length": "14",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "www.httpbin.org",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0",
    "X-Amzn-Trace-Id": "Root=1-633b00af-320604742936717c3ede322f"
  },
  "json": null,
  "origin": "120.227.32.26",
  "url": "https://www.httpbin.org/post"
}

高级用法:

  • class HTTPDefaultErrorHandler(用于处理HTTP响应错误,所有错误都会抛出HTTPError类型的异常)
  • class HTTPRedirectHandler(用于处理重定向)
  • class HTTPCookieProcessor(用于处理Cookie)
  • class ProxyHandler(用于设置代理,代理默认为空)
  • class HTTPPasswordMgr(用于管理密码,它维护着用户名密码的对照表)
  • class HTTPBasicAuthHandler(用于管理认证,如果一个链接在打开时需要认证,那么可以用这类来解决认证问题)

urllib.request官网还提供了其他方法和类。
注:由于下一章requests库是在urllib.request的基础上进行的封装,且requests库比urllib.request更强大,实际使用中更广泛。所以urllib.request可作为了解,剩下的类和方法不在举例说明,感兴趣的可以通过官网自行学习。

2、error处理异常
urllib库中的error模块定义了有request模块产生的异常。当请求出现异常时,request模块就会抛出error模块中定义的异常。
①URLError:该类继承自OSError类,是error异常模块的基类。

  • reason: 此错误的原因。 它可以是一个消息字符串或另一个异常实例。

②HTTPError:是URLError的子类,专门用来处理HTTP请求错误,例如认证失败等。

  • code:返回HTTP状态码,例如404表示网页不错在等。
  • reason:同父类一样,用于返回错误的原因。
  • headers:返回请求头

3、parse解析链接
该模块定义了处理URL的标准接口,例如实现URL各部分的抽取、合并以及链接转换。它支持处理如下协议的URL处理:file、ftp、gopher、hdl、http、https、imap、mailto、mms、news、nntp、prospero、rsync、rtsp、rtspu、sftp、sip、sips、snews、svn、svn+ssh、telnet和wais。
①urlparse:实现url的识别和分段。
urllib.parse.urlparse(urlstring, scheme=’ ', allow_fragments=True)

  • urlstring:必填项,即待解析的URL。
  • scheme:这是默认的协议,一般在urlstring中加入协议,此项可忽略(只有当url中没带协议时,该参数才会生效)。
  • allow_fragment:是否忽略锚点,如果设为True,fragment会被解析为path、params或query中的一部分,fragment为空。

输入:

from urllib.parse import urlparse
result = urlparse('https://www.baidu.com/index.html;user?id=5#comment')
print(type(result), result, sep='\n')

输出:

<class 'urllib.parse.ParseResult'>
ParseResult(scheme='https', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')

一个标准的链接格式
scheme://netloc/path;params?query#fragment
scheme:协议
netloc:域名
path:访问路径
params:代表参数
query:查询条件query
fragment:锚点,用于直接定位页面内部的下拉位置

②urlunparse:urlparse的对立方法urlunparse,用于构造URL。这个方法接收的参数是一个可迭代对象,其长度必须是6,否则就会抛出参数不足或者过多的异常。
输入:

from urllib.parse import urlunparse
data = ['https','www.baidu.com','/index.html','user','id=6','commment']
print(urlunparse(data))

输出:

https://www.baidu.com/index.html;user?id=6#commment

假如在data里再加入一个‘test’,则输出结果为:

scheme, netloc, url, params, query, fragment, _coerce_result = (
ValueError: too many values to unpack (expected 7)

③urlsplit:与urlparse相似,不过它直解析params这一部分(params会合并到path中),只返回5个结果
④urlunsplit:urlsplit的对立方法就是urlunsplit,接收的参数是一个可迭代对象,其长度必须是5。
⑤urljoin:接收两个参数,第一个参数是base_url,第二个参数是新的链接new_url。urljoin会解析两个参数的scheme、netloc、path三个内容,new_url缺失的内容会用base_url的补充,如果new_url三项内容都存在,base_url是不起作用的。
⑥urlencode:将字典类型序列化get请求参数形式。例如:
user = {'name': 'Jack', 'age': 60} >name=Jack&age=60
⑦parse_qs:返序列化,上述例子颠倒过来。
⑧parse_sql:该方法将参数转化成由元组组成的列表。如下:
name=Jack&age=60
>[('name', 'Jack'), ('age', '60')]
⑨quote:该方法可以将内容转化成URL编码格式。当URL中带中文参数时,有可能导致乱码问题,此时用quote方法可以将中文字符转化成URL编码,for example:

输入:

from urllib.parse import quote
keyword = '关键字'
url = 'https://www.baidu.com/s?wd=' + quote(keyword)
print(url)

输出:

https://www.baidu.com/s?wd=%E5%85%B3%E9%94%AE%E5%AD%97

⑩unquote:解码功能,与quote对立。

4、robotparser分析Robot协议
Robot协议也称作爬虫协议、机器人协议,全名为网络爬虫排除标准,用来告诉爬虫和搜索引擎哪些页面可以抓取、哪些不可以。它通常是一个叫做robots.txt的文本文件,一般放在网站的根目录下。其中User-agent制定爬虫名称,Disallow指定不可爬取的路径,Allow指定可爬取的路径。
通过robotparser解析robots.txt文件

此模块提供了一个单独的类 RobotFileParser,它可以回答关于某个特定用户代理能否在发布了 robots.txt 文件的网站抓取特定 URL 的问题。 有关 robots.txt 文件结构的更多细节,请参阅 http://www.robotstxt.org/orig.html。
class urllib.robotparser.RobotFileParser(url='')
    这个类提供了一些可以读取、解析和回答关于 url 上的 robots.txt 文件的问题的方法。
    set_url(url)  //设置指向 robots.txt 文件的 URL。
    read()   //读取 robots.txt URL 并将其输入解析器。
    parse(lines) //解析行参数。
    can_fetch(useragent, url)  //如果允许 useragent 按照被解析 robots.txt 文件中的规则来获取 url 则返回 True。
    mtime()  //返回最近一次获取 robots.txt 文件的时间。 这适用于需要定期检查 robots.txt 文件更新情况的长时间运行的网页爬虫。
    modified()  //将最近一次获取 robots.txt 文件的时间设置为当前时间。
    crawl_delay(useragent)  //为指定的 useragent 从 robots.txt 返回 Crawl-delay 形参。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None(3.6 新版功能)
    request_rate(useragent) //以 named tuple RequestRate(requests, seconds) 的形式从 robots.txt 返回 Request-rate 形参的内容。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None(3.6 新版功能)
    site_maps()	//list() 的形式从 robots.txt 返回 Sitemap 形参的内容。 如果此形参不存在或者此形参的 robots.txt 条目存在语法错误,则返回 None(3.8 新版功能)

例:

>>> import urllib.robotparser
>>> rp = urllib.robotparser.RobotFileParser()
>>> rp.set_url("http://www.musi-cal.com/robots.txt")
>>> rp.read()
>>> rrate = rp.request_rate("*")
>>> rrate.requests
3
>>> rrate.seconds
20
>>> rp.crawl_delay("*")
6
>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
False
>>> rp.can_fetch("*", "http://www.musi-cal.com/")
True

相关文章:

  • switch循环语句
  • 牛客练习赛#84 F 莫比乌斯反演+杜教筛+技巧+斐波那契数列和gcd的结论+矩阵快速幂
  • ZZNUOJ_用C语言编写程序实现1342:支配值数目(附完整源码)
  • java毕业设计后勤管理系统餐饮评价监督系统(附源码、数据库)
  • 前端基础学习笔记
  • 【TS】联合类型--类型断言--类型推断
  • 谈笑风声的秘密
  • QT影城网上售票系统
  • NetCDF数据在ArcMap中的使用
  • 打怪升级(考验思路)