Python进阶 - HTML获取与解析
来源:互联网 发布:手机淘宝网电脑版登陆 编辑:程序博客网 时间:2024/06/07 06:05
1 URL的处理
1.1 URL介绍
HTML使用同一资源定位符(Universal Resource Locator:URL)来定位Internet上的HTML文档信息。URL语法定义如下:
protocol://auth/path?query
常用协议有:http、https、ftp、mailto、file、telnet
一种包含授权的URL详细语法如下:
protocol://username@passwd:netloc:port/path/filename?param = value#tag
具体示例:
http://www.w3.org/2015/10/Process-20150914/activities.htmlftp://ftp.test.com/pub/index.txt../images/logo.jpgfirst.html
1.2 URL的解析
python中的urllib.urlparse用于对url进行解析。主要方法有urlparse、urljoin、urlsplit、urlunsplit等。
urlparse将URL分为六元组:
scheme://netloc/path;parameters?query#fragment
注意这里并没有将服务器地址和端口地址进行区分。
在解析URL的时候所有的%
转移符都不会被处理。另外除了第一个起始斜线外,分隔符都会被去掉。
urlparse有两个可选参数:
- default_scheme:为不包含协议的url指定协议
- allow_fragments:指示是否可以对地址进行分片。默认为True
1.3 URL拼合
from urllib.parse import *webURL = "http://alice:secret@www.hostname.com:80/%7Ealice/python.cgi\?query = text#sample"r = urlparse(webURL)print(r)# 第一个参数是绝对地址,第二个是相对地址join1 = urljoin("http://www.zeroc.com", "ice.html")print(join1)# 都含有绝对地址,有限采用相对地址中的协议join2 = urljoin("http://www.python.org", "ftp:www.python.org/fag")print(join2)# 当相对url中不含协议时,会将所有字符当做一个路径信息join3 = urljoin("http://www.python.org", "www.python.org/faq")print(join3)# 优先使用相对url地址的服务器地址和路径join4 = urljoin("http://www.python.org", "http://www.python.com/fag")print(join4)
1.4 URL分解
有效的格式化,特殊字符得到转换:
r = urlunsplit(urlsplit("http://www.python.org/faq?"))
1.5 URL的编码与解码
URL中使用的是ASCII字符集,当使用不在字符集中的字符时,就需要进行编码。即使是ASCII字符集中的字符,有些也不能直接使用,常见的情况是不能在URL中使用空格字符。有些字符被称为保留字符,不能在URL中出现,例如斜线/
等。ASCII字符集中的编码规则是:在百分号后面加上两个十六进制数字,与其在ASCII字符表中的数值对应。
大部分的标点符号都需要编码,特别是那些保留字符。一般的,对于不在ASCII字符集中的字符,如果不知道是否应该编码,那么最好进行编码。注意当字符有特殊含义的时候不应进行编码
urllib中的编码解码方法如下:
quote
对URL进行编码quote_plus
同quote编码,进一步将空格变为+
符号unquote
解码unquote_plus
解码,将+
变为空格
1.6 中文的编码与解码
from urllib.parse import quoter = quote("URL编码")unquote(r)
1.7 参数的编码
urlencode用于将查询参数加工成url所需的格式
urlencode([("keyword1", "value1"), ("keyword2", "value2"), ("keyword3", "keyword3")]) #列表中的元素是有序的urlencode({"key1":"val1", "key2":"val2", "key3":"val3"}) #集合中的元素是无序的
urlencode还有一个可选的参数,用于对查询参数中的数据进行控制。默认为False,即当查询参数的value为列表的时候,将其整个用quote_plus进行编码,并作为查询的参数。当其为True时,不会编码。
urlencode([("keyword", ("val1", "val2", "val3"))])urlencode([("keyword", ("val1", "val2", "val3"))], True)
2 获取HTML资源
2.1 使用urlopen和urlretrieve获取HTTP资源
urlopen:
可以读取URL资源,并不能对数据进行seek操作。返回值中有一个可以读的handler,从而可以实现对数据的读取。
from urllib.request import *fp = urlopen("http://www.python.org")print(fp.read())op = open("python.html", "wb") # 从网络获取的数据最好使用二进制方式n = 0while True: s = fp.read(1024) if not s: # 遇到 EOF 时跳出循环 break op.write(s) n = n + len(s)fp.close()op.close()print("retrieved", n, " bytes from", fp.url)
使用代理:
proxies = {"http":"http://www.proxy.com:2137"}urlopen(url, proxies = proxies)
urlretrieve:
直接存储到本地文件。
关于参数 reporthook,用于报告下载进度的一个函数,有三个参数,分别为已获取的文件块的个数、文件块的大小、文件的大小。当文件大小为 -1 时,表明无法获得整个文件的大小,特别是对于ftp流数据而言。
from urllib.request import *def download(url, filename = ""): def reporthook(block_count, block_size, file_size): if file_size == -1: print("Cann't determine the file size, now retrieved", block_count * block_size) else: percentage = int((block_count * block_size * 100.0) / file_size) if percentage > 100: print(" 100% ") else: print(" % d% % " % (percentage)) filehandler, m = urlretrieve(url, filename, reporthook = reporthook) print("Done!") return filehandlerdownload("http://www.python.org", "D:/index.html")
2.2 自定义资源获取方式
urllib中还有URLopener及其继承类FancyURLopener,它们也可以完成URL资源的读取。实际上urlopen方法就是FacyURLopener的一个实例,并通过调用其实例的open方法来实现的。一般来说,使用FancyURLopener就够了,URLopener类主要针对除http、ftp、file以外的协议。
访问需要简单认证的URL资源
FancyURLopener类中有prompt_user_passwd方法来处理用户名和密码,当访问的资源需要使用简单认证进行访问的情况下,将会调用此方法得到用户名和密码。默认情况下会从控制台读取用户名和密码。我们需要对这个函数进行重载,直接在代码中调用我们事先设定的参数即可。
from urllib.request import *class myURLopener(FancyURLopener): def setAuth(self, user, passwd): self.user = user self.passwd = passwd def prompt_user_passwd(self, host, realm): return self.user, self.passwdmyurlopener = myURLopener()myurlopener.setAuth(" user", " passwd")op = myurlopener.open(" http://www.secret.com")
构造文件头元信息
有效避开某些URL资源对于访问的限制
from urllib.request import *opener = FancyURLopener()opener.addheader("User-Agent", "Mozilla/4.0 (compatible;MSIE 6.0; \ windows NT 5.1)")opener.addheader("Accept", "text/html")opener.addheader("Connection", "close")opener.open("http://www.baidu.com")
访问出错的处理方法
HTTP状态码:
301
数据已被删除302
资源临时重定向303
建议访问其他URL307
资源临时性删除401
错误的请求404
访问资源不存在
默认情况下对303错误的处理方法:
def http_error_302(self, url, fp, errcode, errmsg, headers, data = None): delf.tries += 1 if self.maxtries and self.tries >= self.maxtries: if hasattr(self, "http_error_500"): meth = self.http_error_500 else: meth = self.http_error_default self.tries = 0 return meth(url, fp, 500, "Internal Server Error: Redirect Recursion", headers) result = self.redirect_internal(url, fp, errcode, errmsg, headers, data) self.tries = 0 return result
自定义处理方法:
from urllib.request import *class myURLopener(FancyURLopener): def setAuth(self, user, passwd): self.user = user self.passwd = passwd def prompt_user_passwd(self, host, realm): return self.user, self.passwd def http_error_302(self, url, fp, errcode, errmsg, headers, data = None): if "location" in headers: newurl = headers["location"] elif "uri" in headers: newurl = headers["uri"] else: return print(url, "==>", newurl) return FancyURLopener.http_error_302(self, url, fp, errcode, errmsg, headers, data)myurlopener = myURLopener()myurlopener.setAuth(" user", " passwd")op = myurlopener.open(" http://www.secret.com")
2.3 使用httplib获取资源
The httplib module has been renamed to http.client in Python 3.
httplib实现了HTTP和HTTPS协议的客户端部分,一般情况下这个模块并不直接使用,而是作为urllib的基础模块。但实际上,此模块还是比较适用于在访问HTTP资源的时候使用,包括GE和POST方法等等。
3 HTML文档解析
获取到资源之后,结下来便是对HTML文档进行处理了。Python提供了HTMLParser模块来解析HTML文档。另外,由于HTML是属于SGML家族的一员,所以亦可以使用sgmllib模块来处理HTML文档。htmpllib是建立在sgmllib模块上的HTTP文档高级处理模块,可以对HTML进行更细的处理。
3.1 使用HTMLParser模块
HTMLParser小巧、快速、使用简便,利用它可以分析HTML文档中的标签和数据等。HTMLParser采用了一种事件驱动的方式,是的模块在找到了一个特定的对象的时候,可以调用用户定义的函数来进行处理。
处理函数都是以handle_开头的,是HTMLParser的成员函数。具体使用使,先继承HTMLParser类,然后重载这些函数即可。
HTMLParser中的handle_函数如下:
handle_startendtag
处理开始标签和结束标签,比如handle_starttag
处理开始标签,比如handle_endtag
处理结束标签,比如handle_charref
处理特殊字符串,就是以&#开头的,一般是内码表示的字符handle_entityref
处理一些特殊字符,以&开头的,比如handle_data
处理数据,就是data中间的那些数据handle_comment
处理注释handle_decl
处理
3.2 sgmllib的HTML文档处理
Deprecated since version 2.6: The sgmllib module has been removed in Python 3.
3.3 使用htmllib处理HTML文档
Deprecated since version 2.6: The htmllib module has been removed in Python 3.
- Python进阶 - HTML获取与解析
- python解析html获取Url
- Python进阶_2.通过URL获取HTMl内容
- 【python】解析中英文进阶
- python中html解析 HTMLParser与sgmllib
- python模块之HTMLParser: 解析html,获取url
- python模块之HTMLParser: 解析html,获取url
- python模块之HTMLParser: 解析html,获取url
- Python lxml解析HTML并用xpath获取元素
- python模块之HTMLParser: 解析html,获取url
- 用python解析html
- 用python解析html
- 用python解析html
- python解析html/xml
- python HTML解析器
- python html解析
- python 解析html
- python 解析HTML
- hdu 5491(位运算)
- ThinkPHP--空操作处理和空控制器处理
- 第四周项目一 建立单链表
- 高等数学公式---从数学公式到物理模型
- 获取ios设备型号
- Python进阶 - HTML获取与解析
- 从今天开始,每次学习就记个日记,慢慢来
- 【读书笔记】iOS-KVC
- canvas鼠标点击散播图片
- 文本框 UITextView
- 熟悉linux-mysql的安装与卸载(centos)
- How to Write an Effective Design Document
- zoj 1610 Count the Colors 线段树区间更新——染色问题
- ZOJ第1240题 灰常简单的题目