python的urllib库用于操作网页URL,并对网页内容进行抓取处理。
urllib包主要包含以下几个模块:
urllib.request - 打开和读取URL。
urllib.error - 包含urllib.request抛出的异常。
urllib.parse - 解析URL。
urllib.robotparser - 解析robots.txt。
一、urllib.request
urllib.request 定义了一些打开URL的函数和类,包含授权验证、重定向、浏览器cookies等。
urllib.request 也可模拟浏览器的一个请求发起过程。
使用urllib.request的urlopen方法来打开一个URL,语法格式:
urlli.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
url --url地址
data --发送到服务器的其他数据对象,默认为None。
timeout -- 设置访问超时时间。
cafile、capath -- cafile为CA证书,capath为CA证书的路径,使用HTTPS时需要用到。
cadefault --已废弃。
context -- ssl.SSLContext,用来指定SSL设置。
实例:
打开一个url,并使用read函数获取网页HTML的实体代码。
from urllib.request import urlopen
myURL = urlopen("https://www.runoob.com/")
print(myURL.read())
read()是读取整个网页内容,也可指定读取的长度,如read(300)。除了read函数,还包含以下两个读取网页内容的函数:
readline() - 读取文件的一行内容。
readlines() - 读取文件全部内容,它会把读取的内容赋值给一个列表变量,可遍历输出。
from urllib.request import urlopen
myURL = urlopen("https://www.runoob.com/")
#读取文件全部内容
print(myURL.read())
#读取一行内容
print(myURL.readline())
#读取全部内容
lines = myURL.readlines()
for i in lines:
print(i)
判断网页是否可以正常访问,可以使用getcode()函数获取网页状态,返回200说明网页正常,404说明网页不存在:
#获取网页响应码
print(myURL.getcode())
将抓取的网页保存到本地,使用文件的write方法:
#将网页保存到本地
f = open("runoob_url_test.html", "wb")
content = myURL.read()
f.write(content)
f.close()
可看到本地多了runoob_url_test.html文件。
URL的编码和解码可以使用urllib.request.quote()和urllib.request.unquote()方法:
import urllib.request
#编码
encode_url = urllib.request.quote("https://www.runoob.com/")
print(encode_url)
#解码
unencode_url = urllib.request.unquote(encode_url)
print(unencode_url)
二、模拟头部信息
抓取网页时一般需要对headers(网页头信息)进行模拟,需要用到urllib.request.Request类:
class urllib.request.Request(url, data=None, headers={}, orign_req_host=None, unverifiable=False, method=None)
url -- url地址
data --发送到服务器的其他数据对象,默认为None。
headers -- HTTP请求头信息,字典格式。
origin_req_host --请求的主机地址,IP或域名。
unverifiable --很少用整个参数,用于设置网页是否需要验证,默认False。
method -- 请求方法,如:GET、POST、DELETE、PUT等。
import urllib.request
#获取网页请求头信息
url = "https://www.runoob.com/?s="
keyword = "Python 教程"
key_code = urllib.request.quote(keyword) #对请求进行编码
url_all = url + key_code
#头部信息
header = {'User-Agent':'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
reqest = urllib.request.Request(url_all, headers=header)
response = urllib.request.urlopen(reqest).read()
#将响应文件保存到本地
fh = open("urllib_test_runoob_search.html", "wb")
fh.write(response)
fh.close()
表单POST传递数据,我们先创建一个表单(使用PHP创建),py3_urllib_test.php'代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com) urllib POST 测试</title>
</head>
<body>
<form action="" method="post" name="myForm">
Name: <input type="text" name="name"><br>
Tag: <input type="text" name="tag"><br>
<input type="submit" value="提交">
</form>
<hr>
<?php
// 使用 PHP 来获取表单提交的数据,你可以换成其他的
if(isset($_POST['name']) && $_POST['tag'] ) {
echo $_POST["name"] . ', ' . $_POST['tag'];
}
?>
</body>
</html>
import urllib.reqest
import urllib.parse
#提交到表单页面
url_form = "https://www.runoob.com/try/py3/py3_urllib_test.php"
data = {"name": "RUNOOB", "tag":"菜鸟教程"} #提交数据
#头部信息
header = {'User-Agent':'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'}
#对参数进行编码,解码使用urllib.parse.urldecode
data = urllib.parse.urlencode(data).encode("utf8")
reqest1 = urllib.request.Request(url_form, data, header)
response1 = urllib.request.urlopen(reqest1).read()
fw = open("urllib_test_post_runoob.html", "wb")
fw.write(response1)
fw.close()
三、urllib.error
为urllib.request所引发的异常定义了异常类,基础异常类时URLError。
urllib.error包含了两个方法:URLError和HTTPError。
URLError是OSError的子类,用于处理程序在遇到问题是引发的异常,其属性包括reason-引发异常的原因。
HTTPError是URLError的子类,用于处理特殊HTTP错误,例如作为认真请求时报的异常,包括属性:code-HTTP状态码,reason-引发异常的原因,headers-导致HTTPError的HTTP请求的响应头。
如下,对不存在的网页进行数据抓取并处理异常:
import urllib.request
import urllib.error
#对不存在的网页进行数据抓取并处理异常
try:
myURL1 = urllib.request.urlopen("https://www.runoob.com/no.html")
except urllib.error.HTTPError as e:
if e.code == 404:
print(404)
四、urllib.parse
用于解析URL,格式如下:
urllib.parse.urlparse(urlstring, schema='', allow_fragments=True)
urlstring -- 字符串url地址
schema --协议类型
allow_fragments --参数false时则无法识别片段标识符。相反,他们被解析为路径、参数或查询组件的一部分,并在返回值中设置fragment为空字符串。
#解析URL
from urllib.parse import urlparse
o = urlparse("https://www.runoob.com/?s=python+%E6%95%99%E7%A8%8B")
print(o)
输出:
ParseResult(scheme='https', netloc='www.runoob.com', path='/', params='', query='s=python+%E6%95%99%E7%A8%8B', fragment='')
从结果可以看出,内容是一个元组,包含 6 个字符串:协议,位置,路径,参数,查询,判断。
直接读取协议内容:
#直接读取协议内容
print(o.scheme)
参数完整内容:
属性 | 索引 | 值 | 值(如果不存在) |
---|---|---|---|
| 0 | URL协议 | scheme 参数 |
| 1 | 网络位置部分 | 空字符串 |
| 2 | 分层路径 | 空字符串 |
| 3 | 最后路径元素的参数 | 空字符串 |
| 4 | 查询组件 | 空字符串 |
| 5 | 片段识别 | 空字符串 |
| 用户名 |
| |
| 密码 |
| |
| 主机名(小写) |
| |
| 端口号为整数(如果存在) |
|
五、urllib.robotparser
用于解析robots.txt文件。
robots.txt(统一小写)是一种存放于网站根目录下的 robots 协议,它通常用于告诉搜索引擎对网站的抓取规则。robots.txt是一个协议,而不是一个命令。robots.txt是搜索引擎中访问网站的时候要查看的第一个文件。robots.txt文件告诉蜘蛛程序(网络爬虫)在服务器上什么文件是可以被查看的。
robots.txt语法:最简单的 robots.txt 文件使用两条规则:
· User-Agent: 适用下列规则的漫游器
· Disallow: 要拦截的网页
SEO(搜索引擎优化):鉴于网络安全与隐私的考虑,搜索引擎遵循robots.txt协议。通过根目录中创建的纯文本文件robots.txt,网站可以声明不想被robots访问的部分。每个网站都可以自主控制网站是否愿意被搜索引擎收录,或者指定搜索引擎只收录指定的内容。当一个搜索引擎的爬虫访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果该文件不存在,那么爬虫就沿着链接抓取,如果存在,爬虫就会按照该文件中的内容来确定访问的范围
————————————————
原文链接:https://blog.youkuaiyun.com/kalision/article/details/7918528
urllib.robotparser提供了RobotFileParser类,语法如下:
class urllib.robotparser.RobotFileParser(url='')
该类提供了一些可以读取、解析robots.txt文件的方法:
方法 | 参数 | 作用 |
set_url(url) | url - robots.txt文件路径 | 设置robots.txt文件路径 |
read() | 无 | 读取robots.txt文件内容并输入解析器 |
parse(lines) | lines -行数 | 解析行参数 |
can_fetch(useragent, url) | ueseragent-代理用户 url-robots.txt文件路径 | 如果允许 useragent 按照被解析 robots.txt 文件中的规则来获取 url 则返回 True |
mtime() | 无 | 返回最近一次获取robots.txt文件的时间,适用于需要定期检查robots文件更新情况的长时间网络爬虫 |
modified() | 无 | 将最近一次获取文件的时间设置为当前时间 |
crawl_delay(useragent) | useragent-代理用户 | 为指定的useragent获取从robots.txt返回Crawl-delay形参,如果此形参不存在或不使用于指定的useragent或者此形参的robots.txt条目存在语法错误,则返回None |
request_rate(useragent) | useragent-代理用户 | 以 named tuple RequestRate(requests, seconds) 的形式从 robots.txt 返回 Request-rate 形参的内容。 如果此形参不存在或不适用于指定的 useragent 或者此形参的 robots.txt 条目存在语法错误,则返回 None |
site_maps() | 无 | 以list的形式从robots.txt返回Sitemap形参内容。如果此形参不存在或形参的 robots.txt 条目存在语法错误,则返回 None |
>>> 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