
虽然说XPath比正则表达式用起来方便,但是没有最方便,只有更方便。我们的BeautifulSoup库就能做到更方便的爬取想要的东西。
使用之前,还是老规矩,先安装BeautifulSoup库,指令如下:
其中文开发文档:
BeautifulSoup库是一个强大的Python语言的XML和HTML解析库。它提供了一些简单的函数来处理导航、搜索、修改分析树等功能。
BeautifulSoup库还能自动将输入的文档转换为Unicode编码,输出文档转换为UTF-8编码。
所以,在使用BeautifulSoup库的过程中,不需要开发中考虑编码的问题,除非你解析的文档,本身就没有指定编码方式,这才需要开发中进行编码处理。
下面,我们来详细介绍BeautifulSoup库的使用规则。
下面,我们来详细介绍BeautifulSoup库的重点知识。
首先,BeautifulSoup库中一个重要的概念就是选择解释器。因为其底层依赖的全是这些解释器,我们有必要认识一下。博主专门列出了一个表格:
从上面表格观察,我们一般爬虫使用lxml HTML解析器即可,不仅速度快,而且兼容性强大,只是需要安装C语言库这一个缺点(不能叫缺点,应该叫麻烦)。
要使用BeautifulSoup库,需要和其他库一样进行导入,但你虽然安装的是beautifulsoup4,但导入的名称并不是beautifulsoup4,而是bs4。用法如下:
运行之后,输出文本如下:
基础的用法很简单,这里不在赘述。从现在开始,我们来详细学习BeautifulSoup库的所有重要知识点,第一个就是节点选择器。
所谓节点选择器,就是直接通过节点的名称选择节点,然后再用string属性就可以得到节点内的文本,这种方式获取最快。
比如,基础用法中,我们使用h1直接获取了h1节点,然后通过h1string即可得到它的文本。但这种用法有一个明显的缺点,就是层次复杂不适合。
所以,我们在使用节点选择器之前,需要将文档缩小。比如一个文档很多很大,但我们获取的内容只在id为blog的p中,那么我们先获取这个p,再在p内部使用节点选择器就非常合适了。
HTML示例代码:
下面的一些示例,我们还是使用这个HTML代码进行节点选择器的讲解。
这里,我们先来教会大家如何获取节点的名称属性以及内容,示例如下:
运行之后,效果如下:
一般来说一个节点的子节点有可能很多,通过上面的方式获取,只能得到第一个。如果要获取一个标签的所有子节点,这里有2种方式。先来看代码:
运行之后,效果如下:
如上面代码所示,我们有2种方式获取所有子节点,一种是通过contents属性,一种是通过children属性,2者遍历的结果都是一样的。
既然能获取直接子节点,那么获取所有子孙节点也是肯定可以的。BeautifulSoup库给我们提供了descendants属性获取子孙节点,示例如下:
运行之后,效果如下:
同样的,在实际的爬虫程序中,我们有时候也需要通过逆向查找父节点,或者查找兄弟节点。
BeautifulSoup库,给我们提供了parent属性获取父节点,同时提供了next_sibling属性获取当前节点的下一个兄弟节点,previous_sibling属性获取上一个兄弟节点。
示例代码如下:
运行之后,效果如下:
对于节点选择器,博主已经介绍了相对于文本内容较少的完全可以这么做。但实际的爬虫爬的网址都是大量的数据,开始使用节点选择器就不合适了。所以,我们要考虑通过方法选择器进行先一步的处理。
find_all()方法主要用于根据节点的名称、属性、文本内容等选择所有符合要求的节点。其完整的定义如下所示:
实战还是测试上面的HTML,我们获取name=a,attr={"class":"aaa"},并且文本等于text="Python板块"板块的节点。
示例代码如下所示:
运行之后,效果如下所示:
find()与find_all()仅差一个all,但结果却有2点不同:
1find()只查找符合条件的第一个节点,而find_all()是查找符合条件的所有节点2find()方法返回的是bs4elementTag对象,而find_all()返回的是bs4elementResultSet对象
下面,我们来查找上面HTML中的a标签,看看返回结果有何不同,示例如下:
运行之后,效果如下:
首先,我们来了解一下CSS选择器的规则:
1classname:选取样式名为classname的节点,也就是class属性值是classname的节点2#idname:选取id属性为idname的节点3nodename:选取节点名为nodename的节点
一般来说,在BeautifulSoup库中,我们使用函数select()进行CSS选择器的 *** 作。示例如下:
这里,我们选择class等于li1的节点。运行之后,效果如下:
因为,我们需要实现嵌套CSS选择器的用法,但上面的HTML不合适。这里,我们略作修改,仅仅更改
任何事件在微博的发酵速度绝对是各大平台中最快的,如果把微博评论爬取下来,进行处理和分析,就能对某个事件的不同立场和风向有了全面的了解和掌握。
当然,评论量大的微博在爬取时耗费时间较长,为了缩短 *** 作时间,找了老罗的一条评论不太多的微博进行演示。
Sitemap name : weibo
Start URL : >
这里有各种策略用于定位网页中的元素(locate elements),你可以选择最适合的方案,Selenium提供了一下方法来定义一个页面中的元素:
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
下面是查找多个元素(这些方法将返回一个列表):find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
除了上面给出的公共方法,这里也有两个在页面对象定位器有用的私有方法。这两个私有方法是find_element和find_elements。
常用方法是通过xpath相对路径进行定位,同时CSS也是比较好的方法。举例:
[html] view plain copy
<html>
<body>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
<input name="continue" type="button" value="Clear" />
</form>
</body>
<html>
定位username元素的方法如下:[python] view plain copy
username = driverfind_element_by_xpath("//form[input/@name='username']")
username = driverfind_element_by_xpath("//form[@id='loginForm']/input[1]")
username = driverfind_element_by_xpath("//input[@name='username']")
[1] 第一个form元素通过一个input子元素,name属性和值为username实现[2] 通过id=loginForm值的form元素找到第一个input子元素
[3] 属性名为name且值为username的第一个input元素
二 *** 作元素方法
在讲述完定位对象(locate elements)之后我们需要对该已定位对象进行 *** 作,通常所有的 *** 作与页面交互都将通过WebElement接口,常见的 *** 作元素方法如下:
clear 清除元素的内容
send_keys 模拟按键输入
click 点击元素
submit 提交表单
举例自动访问FireFox浏览器自动登录163邮箱。
[python] view plain copy
from selenium import webdriver
from seleniumwebdrivercommonkeys import Keys
import time
# Login 163 email
driver = webdriverFirefox()
driverget("")
elem_user = driverfind_element_by_name("username")
elem_userclear
elem_usersend_keys("15201615157")
elem_pwd = driverfind_element_by_name("password")
elem_pwdclear
elem_pwdsend_keys("")
elem_pwdsend_keys(KeysRETURN)
#driverfind_element_by_id("loginBtn")click()
#driverfind_element_by_id("loginBtn")submit()
timesleep(5)
assert "baidu" in drivertitle
driverclose()
driverquit()
首先通过name定位用户名和密码,再调用方法clear()清除输入框默认内容,如“请输入密码”等提示,通过send_keys("")输入正确的用户名和密码,最后通过click()点击登录按钮或send_keys(KeysRETURN)相当于回车登录,submit()提交表单。PS:如果需要输入中文,防止编码错误使用send_keys(u"中文用户名")。
三 WebElement接口获取值
通过WebElement接口可以获取常用的值,这些值同样非常重要。
size 获取元素的尺寸
text 获取元素的文本
get_attribute(name) 获取属性值
location 获取元素坐标,先找到要获取的元素,再调用该方法
page_source 返回页面源码
drivertitle 返回页面标题
current_url 获取当前页面的URL
is_displayed() 设置该元素是否可见
is_enabled() 判断元素是否被使用
is_selected() 判断元素是否被选中
tag_name 返回元素的tagName
最近工作中很多重复性的web工具处理,想看能否用脚本进行简化,便认真去了解了下selenium,看了些博客资料后,个人习惯还是去看书(书籍介绍比较系统)便去搜了lib gen 下,才了解到seleniumIDE的。
还有一种解决方法是,让程序等待在那里,手动输入用户名密码,然后继续。
可以单步调试查看find_element 返回的元素属性,一般在text字段中,私下试了几个招聘网站,多数页面都是div分块,配合table td以及列表ul/ui等元素布局的方式来呈现,摸索下都是成规律的。
class后面是两个分开的属性,你只要写一个就行了。写俩就不能用空格。
rs = webfind_element_by_class_name('rate-count')text
Beautiful Soup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库,它提供了一些简单的 *** 作方式来帮助你处理文档导航,查找,修改文档等繁琐的工作。因为使用简单,所以 Beautiful Soup 会帮你节省不少的工作时间。
你可以使用如下命令安装 Beautiful Soup。二选一即可。
Beautiful Soup 不仅支持 Python 标准库中的 HTML 解析器,还支持很多第三方的解析器,比如 lxml,html5lib 等。初始化 Beautiful Soup 对象时如果不指定解析器,那么 Beautiful Soup 将会选择最合适的解析器(前提是你的机器安装了该解析器)来解析文档,当然你也可以手动指定解析器。这里推荐大家使用 lxml 解析器,功能强大,方便快捷,而且该解析器是唯一支持 XML 的解析器。
你可以使用如下命令来安装 lxml 解析器。二选一即可。
Beautiful Soup 使用来起来非常简单,你只需要传入一个文件 *** 作符或者一段文本即可得到一个构建完成的文档对象,有了该对象之后,就可以对该文档做一些我们想做的 *** 作了。而传入的文本大都是通过爬虫爬取过来的,所以 Beautiful Soup 和 requests 库结合使用体验更佳。
Beautiful Soup 将复杂的 HTML 文档转换成一个复杂的树形结构,每个节点都是 Python 对象,所有对象可以归纳为 4 种: Tag,NavigableString,BeautifulSoup,Comment。
Tag 就是 HTML 的一个标签,比如 p,p 标签等,也是我们用的最多的一个对象。
NavigableString 指标签内部的文字,直译就是可遍历的字符串。
BeautifulSoup 指一个文档的全部内容,可以当成一个 Tag 来处理。
Comment 是一个特殊的 NavigableString,其输出内容不包括注视内容。
为了故事的顺利发展,我们先定义一串 HTML 文本,下文的所有例子都是基于这段文本的。
Tag 有两个很重要的属性,name 和 attributes。期中 name 就是标签的名字,attributes 是标签属性。标签的名字和属性是可以被修改的,注意,这种修改会直接改变 BeautifulSoup 对象。
由以上例子我么可以看出,可以直接通过点属性的方法来获取 Tag,但是这种方法只能获取第一个标签。同时我们可以多次调用点属性这个方法,来获取更深层次的标签。
如果想获得所有的某个名字的标签,则可以使用 find_all(tag_name) 函数。
我们可以使用 contents 将 tag 以列表方式输出,即将 tag 的子节点格式化为列表,这很有用,意味着可以通过下标进行访问指定节点。同时我们还可以通过 children 生成器对节点的子节点进行遍历。
children 只可以获取 tag 的直接节点,而获取不到子孙节点,descendants 可以满足你。
通过 parent 属性获取标签的父亲节点。 title 的父标签是 head,html 的父标签是 BeautifulSoup 对象,而 BeautifulSoup 对象的父标签是 None。
同时,我们可以通过 parents 得到指定标签的所有父亲标签。
通过 next_sibling 和 previous_sibling 来获取下一个标签和上一个标签。
你可能会纳闷,调用了两次 next_sibling 怎么只有一个输出呢,这方法是不是有 bug 啊。事实上是 p 的第一个 next_sibling 是 p 和 p 之间的换行符 。这个规则对于 previous_sibling 同样适用。
另外,我们可以通过 next_siblings 和 previous_siblings 属性可以对当前节点的兄弟节点迭代输出。在该例子中,我们在每次输出前加了前缀,这样就可以更直观的看到 dib 的第一个 previous_sibling 是换行符了。
通过 next_element 和 previous_element 获取指定标签的前一个或者后一个被解析的对象,注意这个和兄弟节点是有所不同的,兄弟节点是指有相同父亲节点的子节点,而这个前一个或者后一个是按照文档的解析顺序来计算的。
比如在我们的文本 html_doc 中,head 的兄弟节点是 body(不考虑换行符),因为他们具有共同的父节点 html,但是 head 的下一个节点是 title。即 soupheadnext_sibling=title soupheadnext_element=title
同时这里还需要注意的是 title 下一个解析的标签不是 body,而是 title 标签内的内容,因为 html 的解析顺序是打开 title 标签,然后解析内容,最后关闭 title 标签。
另外,我们同样可以通过 next_elements 和 previous_elements 来迭代文档树。由遗下例子我们可以看出,换行符同样会占用解析顺序,与迭代兄弟节点效果一致。
本章节介绍了 Beautiful Soup 的使用场景以及 *** 作文档树节点的基本 *** 作,看似很多东西其实是有规律可循的,比如函数的命名,兄弟节点或者下一个节点的迭代函数都是获取单个节点函数的复数形式。
同时由于 HTML 或者 XML 这种循环嵌套的复杂文档结构,致使 *** 作起来甚是麻烦,掌握了本文对节点的基本 *** 作,将有助于提高你写爬虫程序的效率。
以上就是关于Python爬虫:想听榜单歌曲只需要14行代码即可搞定全部的内容,包括:Python爬虫:想听榜单歌曲只需要14行代码即可搞定、Web Scraper教程(五)爬虫进阶之微博评论的点击「查看更多」爬取、python爬虫简单问题,HTML对象的定位问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)