python urllib

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'代码如下:





菜鸟教程(runoob.com) urllib POST  测试


Name:
Tag:

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)

参数完整内容:

属性

索引

值(如果不存在)

scheme

0

URL协议

scheme 参数

netloc

1

网络位置部分

空字符串

path

2

分层路径

空字符串

params

3

最后路径元素的参数

空字符串

query

4

查询组件

空字符串

fragment

5

片段识别

空字符串

username

用户名

None

password

密码

None

hostname

主机名(小写)

None

port

端口号为整数(如果存在)

None

五、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.csdn.net/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

你可能感兴趣的:(python学习,python)