利用Python完成HTML的解析

/ 0评 / 0

    从零开始的异世界Orz

搭建环境

    在这里我 选择Python2.7的版本,官网下载一路确定。

      在确定PIP安装完成之后进入下一阶段(PIP的安装目录在Python/lib下)

    安装BeautifulSoup:

    在cmd进入python目录下,使用pip install beautifulsoup4(在这里也可以使用Pycharm在线导入下载)

    按装完成后进入python shell 输入from bs4 import BeautifulSoup 若没有错误说明导入成功。也可以使用其他的库:

• lxml
    这个库( http://lxml.de/) 可以用来解析 HTML XML 文档,以非常底层的实现而闻名于世,大部分源代码是用 C 语言写的。虽然学习它需要花一些时间(其实学习曲线越陡峭,表明你可以越快地学会它),但它在处理绝大多数 HTML 文档时速度都非常快。
• HTML parser
    这是 Python 自带的解析库( https://docs.python.org/3/library/html.parser.html)。因为它不用安装(只要装了 Python 就有),所以可以很方便地使用。

第一个程序

   

from urllib import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.runoob.com/html/html-tutorial.html")
bsObj = BeautifulSoup(html.read(),"html.parser")
print (bsObj.h1)

     

    这里解析了标签为h1的第一个标题:


循序渐进

    如果已经确定了目标内容,比如要采集一个名字或者统计数据,也或者是标题。加入目标位置藏在很深的标签当中,而这些标签的外层带着一些没用的属性,我可以写的很暴力的解析方法:

bsObj.findAll("table")[4].findAll("tr")[2].find("td").findAll("div")[1].find("a")

    这样可以提取出来是没错。但是如果HTML发生改变之后,你只能针对新的界面来实现新的方法,轻则稍加修改,重则重写代码,这时候可以寻找其他办法:

寻找“打印此页”的链接,或者看看网站有没有 HTML 样式更友好的移动版(把自己的请求头设置成处于移动设备的状态,然后接收网站移动版//亦或者F12,查看手机版样式)。
寻找隐藏在 JavaScript 文件里的信息。要实现这一点,你可能需要查看网页加载的JavaScript 文件。 我曾
虽然网页标题经常会用到,但是这个信息也许可以从网页的 URL 链接里获取。

如果你要找的信息只存在于一个网站上, 别处没有,那你确实是运气不佳。如果不只限于这个网站, 那么你可以找找其他数据源。有没有其他网站也显示了同样的数据?

    尤其是在面对埋藏很深或格式不友好的数据时, 千万不要不经思考就写代码,一定要三思而后行。先明确思路和目标在去实现,忌讳盲目编程。

     基本上,每个网站都会有层叠样式表( Cascading Style SheetCSS)。专门让浏览器和人类可以理解网站内容而设计一个展现样式的层, CSS 的发明却是网络爬虫的福音。 CSS 可以让 HTML 元素呈现出差异化,使那些具有完全相同修饰的元素呈现出不同的样式。比如,有一些标签看起来是这样:

<span class="green"></span>

而另一些标签看起来是这样:

<span class="red"></span>

网络爬虫可以通过 class 属性的值,轻松地区分出两种不同的标签。例如,它们可以用BeautifulSoup 抓取网页上所有的红色文字,而绿色文字一个都不抓。因为 CSS 通过属性准确地呈现网站的样式,大多数新式网站上的 class id 属性资源都非常丰富。测试一下:

from urllib import urlopen
from urllib2 import HTTPError
from bs4 import BeautifulSoup

html = urlopen("http://www.runoob.com/html/html-tutorial.html")
bsOj = BeautifulSoup(html,"html.parser")

namelist = bsOj.findAll("span",{"class":"color_h1"})
for name in namelist:
    print(name.get_text())

依旧是那个熟悉的菜鸟教程:

 

得到以下:

其中BeautifulSoup 里的 find() findAll() 可能是你最常用的两个函数。借助它们,你可以通过标签的不同属性轻松地过滤 HTML 页面,查找需要的标签组或单个标签。
这两个函数非常相似, BeautifulSoup 文档里两者的定义就是这样:

findAll(tag, attributes, recursive, text, limit, keywords)
find(tag, attributes, recursive, text, keywords)

很可能你会发现,自己在 95% 的时间里都只需要使用前两个参数: tag attributes
    标签参数
tag 前面已经介绍过——你可以传一个标签的名称或多个标签名称组成的 Python列表做标签参数。例如,下面的代码将返回一个包含 HTML 文档中所有标题标签的列表:

.findAll({"h1","h2","h3","h4","h5","h6"})

    属性参数 attributes 是用一个 Python 字典封装一个标签的若干属性和对应的属性值。例如,下面这个函数会返回 HTML 文档里红色与绿色两种颜色的 span 标签:

.findAll("span", {"class":{"green", "red"}})

    递归参数 recursive 是一个布尔变量。你想抓取 HTML 文档标签结构里多少层的信息?如果recursive 设置为 TruefindAll 就会根据你的要求去查找标签参数的所有子标签,以及子标签的子标签。如果 recursive 设置为 FalsefindAll 就只查找文档的一级标签。 findAll默认是支持递归查找的( recursive 默认值是 True);一般情况下这个参数不需要设置,除
非你真正了解自己需要哪些信息,而且抓取速度非常重要,那时你可以设置递归参数。

    文本参数 text 有点不同,它是用标签的文本内容去匹配,而不是用标签的属性。

正则表达式

    其实正则表达式极大的扩大了查询的力度和简化了语句,在这不想 多说关于正则表达式(觉得一说就又是一篇2333) 手动给个链接自己看看吧:http://www.runoob.com/regexp/regexp-syntax.html

    别说这东西没用 :请看测试

from urllib import urlopen
from bs4 import BeautifulSoup
import re

html = urlopen("http://www.3lian.com/gif/2015/07-08/88486.html")
bsObj = BeautifulSoup(html,"html.parser")
images = bsObj.findAll("img", {"src": re.compile("//cdn.kelovp.tech/.*\.jpg")})
for image in images:
    print(image["src"])

    (随便百度了个 页面检索了一下)

这里是生成了几个链接,后缀是.jpg的链接。随便点一个:


在网络数据采集时你经常不需要查找标签的内容, 而是需要查找标签属性。比如标签 <a> 指向的 URL 链接包含在 href 属性中,或者 <img> 标签的图片文件包含在 src 属性中,这时获取标签属性就变得非常有用了。对于一个标签对象,可以用下面的代码获取它的全部属性:

myTag.attrs

要注意这行代码返回的是一个 Python 字典对象,可以获取和操作这些属性。比如要获取图片的资源位置 src,可以用下面这行代码:

myImgTag.attrs["src"] 

溜了溜了

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注