urllib.request 定义了一些打开 URL 的函数和类,包含授权验证、重定向、浏览器 cookies等。
urllib.request 可以模拟浏览器的一个请求发起过程。
我们可以使用 urllib.request 的 urlopen 方法来打开一个 URL
语法:
urllib.request.urlopen(url, data=None, [timeout, ], cafile=None, capath=None, cadefault=False, context=None)
参数说明:
from urllib import request with request.urlopen(r"http://www.xbiquge.la/10/10489/4534454.html") as f: data = f.read() print(data)
读取HTML文档的方式:
read(size)
:读取指定长度的文档,不设置size,读取表示整个文档readline()
:读取文档的一行readlines()
: 读取文件的全部内容,它会把读取的内容赋值给一个列表变量。urllib.request.urlopen(url).getcode()
:获取打开网页的状态码
我们在对网页进行抓取时,经常需要判断网页是否可以正常访问,这里我们就可以使用 getcode() 函数获取网页状态码,返回 200 说明网页正常,返回 404 说明网页不存在。
from urllib import request code = request.urlopen("http://www.xbiquge.la/10/10489/4535761.html").getcode() print(code)
我们抓取网页一般需要对 headers(网页头信息)进行模拟,这时候需要使用到 urllib.request.Request 类创建request对象来模拟浏览器发送请求。
语法:
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
参数描述:
常用成员:
req.host
:设置或者返回请求的主机或者端口req.origin_req_host
:设置或者返回请求的原始主机,不含端口。req.data
:设置或者返回请求数据req.get_method()
:返回一个表示HTTP请求方法的字符串。req.add_header(key,value)
:添加头部信息req.method
:设置或者返回请求方法urlparse()
:将一个URL解析为6个组件,返回一个名为tuple的6个条目。
语法:
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
参数:
返回值:内容是一个元组,包含 6 个字符串:协议,位置,路径,参数,查询,判断。
属性 | 索引 | 值 | 值(如果不存在) |
---|---|---|---|
scheme |
0 | URL协议 | scheme 参数 |
netloc |
1 | 网络位置部分 | 空字符串 |
path |
2 | 分层路径 | 空字符串 |
params |
3 | 最后路径元素的参数 | 空字符串 |
query |
4 | 查询组件 | 空字符串 |
fragment |
5 | 片段识别 | 空字符串 |
username |
用户名 | None |
|
password |
密码 | None |
|
hostname |
主机名(小写) | None |
|
port |
端口号为整数(如果存在) | None |
URL引用函数关注于获取程序数据,并通过引用特殊字符和对 非ascii 文本进行适当编码,使其作为URL组件使用时更加安全。如果上面的URL解析函数还没有覆盖该任务,它们还支持颠倒这些操作,从URL组件的内容重新创建原始数据。
quote()
:使用%xx转义替换字符串中的特殊字符。用于将中文编码(因为中文使用Unicode)。字母、数字和字符“_”。-~'从不被引用,
语法:
urllib.parse.quote(string, safe='/', encoding=None, errors=None)
参数:
unquote()
:用对应的单字符替换%xx转义。一般用于把字符串解码为中文(非ASCII码字符)
语法:
urllib.parse.unquote(string, encoding='utf-8', errors='replace')
参数:可选encoding和errors参数指定如何将百分比编码的序列解码为bytes.decode()方法所接受的Unicode字符。
urlencode()
:将映射对象或可能包含str或bytes对象的二元元组序列转换为百分比编码的ASCII文本字符串。如果生成的字符串被用作带有urlopen()函数的POST操作的数据,那么它应该被编码为字节(encode('utf-8')),否则将导致TypeError。
语法:
urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)
参数:
返回值:结果字符串是由'&'字符分隔的一系列键=值对,其中键和值都被quote_via函数引用。默认情况下,quote_plus()用于引用值,这意味着空格被引用为'+'字符,'/'字符被编码为%2F,这符合GET请求的标准(application/x-www-form-urlencoded)。可以作为quote_via传递的另一个函数是quote(),它将空格编码为%20,而不编码'/'字符。为了最大限度地控制引用的内容,请使用quote并指定一个值以保证安全。
urllib.robotparser 用于解析 robots.txt 文件。
robots.txt(统一小写)是一种存放于网站根目录下的 robots 协议,它通常用于告诉搜索引擎对网站的抓取规则。
urllib.robotparser 提供了 RobotFileParser 类
语法:
class urllib.robotparser.RobotFileParser(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。request_rate(useragent)
-以 named tuple RequestRate(requests, seconds) 的形式从 robots.txt 返回 Request-rate 形参的内容。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None。site_maps()
- 以 list() 的形式从 robots.txt 返回 Sitemap 形参的内容。 如果此形参不存在或者此形参的 robots.txt 条目存在语法错误,则返回 None。###########################GET 请求########################### from urllib import parse, request # 找到页面的搜索框控件: # action = "https://docs.djangoproject.com/en/3.2/search/" # name = q url = "https://docs.djangoproject.com/en/3.2/search/?q=" # 如果name是中文,就需要使用parse.quote(name)进行编码,否则会报错 name = "admin" all = url + parse.quote(name) # 实例化请求对象 req = request.Request(all) # 添加请求头 req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/66.0.3359.170 Safari/537.36") # 开始向浏览器发起请求,并且读取页面数据 r = request.urlopen(req).read() # 打开指定本地路径,准备开始写入文件 with open('./django_down.html','wb') as f: f.write(r)
###########################POST 请求###########################