urllib库是python内置库,并不需要我们额外安装。
通过它,我们就可以完成请求和响应,得到网页内容。
现在,我们来详细看一看:
一、urllib库构成
而urllib库包含以下四个模块:
- urllib.request:用于打开和读取URL,相当于在浏览器输入网址并按下回车。
- urllib.parse:提供处理URL的功能。
- urllib.error:定义了在使用
urllib.request
过程中可能出现的异常类。 - urllib.robotparser:用于解析和处理robots.txt文件,判断网站是否可以爬取。
二、urllib库使用
(1)爬取源代码
我们以Pycharm网站为例:
先导入request库,然后写入代码:
import urllib.request
a=urllib.request.urlopen(r'https://www.jetbrains.com/zh-cn/pycharm/')
print(a.read().decode('utf-8'))
其中的urlopen,用来打开和读取 URL 地址。
运行后,我们可以看到:
输出框中的,便是网页的源代码,
有了源代码,我们想要爬取的图片、链接也就都有了
(tips:有的网站有反爬措施,日后再说如何解决)
当然了,如果我们想要它输出一些具体的内容,比如status、getheaders等
我们可以这么写:
(2)urlopen的参数
在上述代码行
a=urllib.request.urlopen(r'https://www.jetbrains.com/zh-cn/pycharm/')中
括号里看到的便是url 参数,作为网址,不必多说,咱们已经见过
然而它还有其他的可选参数(可写可不写):
下面我们来看一看他们的具体作用:
1.data参数
data参数,用来给链接传递数据。
什么意思呢?
就是,我们之前代码中的网址,是GET请求,是直接点链接就进去的那种
但是如果遇到POST请求,我们就需要提交一份表单了(即需要输入账号密码的那种)
这时候,我们就可以用data参数,直接将数据输入进去
换句话说:如果你想通过POST方法发送数据给服务器,可以通过这个参数提供数据。
我们通过实例来看一下:
假如我传递一个name参数,值为Asir
import urllib.request
import urllib.parse
#将字典转换为URL编码的字符串,再转为字节
data=bytes(urllib.parse.urlencode({'name':'Asir'}),encoding='utf-8')
a=urllib.request.urlopen('https://www.httpbin.org/post',data=data)
print(a.read().decode('utf-8'))
解释:
因为data
参数通常是字节数据类型,所以采用bytes()进行格式转化
urllib.parse.urlencode的作用在于将字典转换为URL编码的字符串
另外,这里的网址https://www.httpbin.org/post,是一个提供http测试的链接。
输出:
我们可以看到在form一栏下多了名为name的参数,其值为Asir
2.timeout参数
timeout参数用来设置超时时间(单位秒),即如果请求超出了这个时间,还没有得到响应,就抛出异常
示例格式如下:
a=urllib.request.urlopen('https://www.httpbin.org/post',data=data,timeout=0.1)
至此,我们已经可以实现对网页的简单抓取。
但是,这个因为过于简单了,所以我们还需要其他参数来补充:
3.headers参数
用来伪装成浏览器
谷歌示例格式:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0'}
4.method参数
用于指定HTTP请求方法(如 "GET" 或 "POST")
(3)示例
完整代码示范如下:
import urllib.request
import urllib.parse
#提前写好各参数
url='https://www.httpbin.org/post'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0'}
dict={'name':'Asir'}
data=bytes(urllib.parse.urlencode(dict),encoding='utf-8')
#创建请求对象
a=urllib.request.Request(url=url,data=data,headers=headers,method='POST')
#打开该对象
response=urllib.request.urlopen(a)
#输出响应
print(response.read().decode('utf-8'))
首先提前写好各参数:url(网址)、headers(请求头:用于伪装)、dict(传递内容)、data
然后将各参数放置到urllib.request.Request()中
由此,构建了一个完整的请求。
然后我们打开该请求对象,并赋值给response
最后以utf-8解码后输出
结果如下:
除此之外,还有一些高级用法,我们结合部分实例讲解:
(了解步骤原理即可)
三、几个实例
(1)验证
在访问网址时,有时会弹出认证窗口,
即,输入账户名+密码才能下一步。
而爬虫,关于它的解决办法如下:
借助一些模块即可完成:
from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError
注:这样导入可以使得下文写模块更简单。如,之前要写urllib.request.abc,那么现在写abc.即可
之后我们提前写好网址、账号名、密码:
url='某某某'
username='Asir'
password='123'
再创建一个实例,用来存储 URL 和对应的认证信息。
p=HTTPPasswordMgrWithDefaultRealm()
将用户名和密码添加到 p
中,与指定的 URL关联。None
表示没有特定的认证域。
p.add_password(None,url,username,password)
创建一个 HTTPBasicAuthHandler
实例,使用 p
中存储的认证信息,在发送请求时自动添加基本认证头部。
auth_handler=HTTPBasicAuthHandler(p)
创建一个 opener,这个 opener 在发送请求时会自动使用基本认证信息。
openr=build_opener(auth_handler)
最后,发送请求并处理响应
try:
#发送 HTTP 请求到指定的 URL。由于 openr 已经包含了认证信息,它会带着基本认证头发送请求。
result=openr.open(url)
#读取返回的响应内容,并将其解码为 UTF-8 格式的字符串。
html=result.read().decode('utf-8')
print(html)
#如果请求过程中发生错误,捕获并输出错误原因。
except URLError as e:
print(e.reason)
之后获取的结果便是打开成功后的网页源代码。
(2)代理
如果要添加代理,
我们可以这么写:
from urllib.error import URLError
from urllib.request import ProxyHandler,build_opener
a=ProxyHandler(
{'http': 'http://127.0.0.1:8080',
'https': 'https://127.0.0.1:8080'}
)
opener=build_opener(a)
try:
……
当然这里需要先在本地搭建一个HTTOP代理,并让其运行在8080端口上