21CTO社区导读:在本篇文章里,我们将讨论使用Python进行网页抓取以及如何引用多个库,如Beautifusoup,Selenium库,以及JavaScript的PhantomJS库来抓取网页。
在本文中,我们将学习到如何抓取静态页面,Ajax内容、iFrame、处理Cookie等内容。
关于网页抓取
网页抓取是从Web中提取数据的过程,可以用于分析数据,提取有用的信息。
可以将抓取的数据存储到数据库里,也可以保存为任何格式的文件格式,比如CSV,XLS等,可用于其它软件再编辑。
在Python语言的世界中,抓取的数据还可以传给类似NLTK这样的库,以进一步处理。
综合来讲,网页抓取可以帮助我们从不同的页面中下载数据,能够创造更多的价值,让更多的人们受益。
您可能会想,为啥我们不用Google来抓取网页呢?我们不用在此发明轮子,网页抓取不是用来开发搜索引擎。
我们可以抓取竞争对手的网页,分析数据,掌握他们的客户对产品的满意度,有了抓取,这一切都是免费的。比如像Moz这样的搜索引擎优化工具可以分解和抓取整个网络,处理和分析数据,这样我们就可以看到人们的兴趣以及如何在同一领域与其他个竞品做比较。
总体而言,网页抓取好处多多。
如何使用BeautifulSoup
假设你有一些Python的基础知识,我们将BeautifulSoup做为第一个网页抓取库。
下面开始安装 BeautifulSoup,可以使用pip,可以使用源码方式安装。如:
pipinstall beautifulsoup4
检查它是否安装成功,请使用你的Python编辑器输入如下内容检测:
frombs4 import BeautifulSoap
然后运行它:
pythonmyfile.py
如果运行没有错误 ,则意味着BeautifulSoup安装成功。现在让我们看看如何使用Beautifulsoup。
第一个网页爬虫
fromurllib.request import urlopen
frombs4 import BeautifulSoup
html= urlopen("https://www.python.org/")
res =BeautifulSoup(html.read(),"html5lib");
print(res.title)
该程序执行结果如下:
我们使用urlopen连接要抓取的网址,然后使用html.read()方法读取和返回HTML。返回的HTML内容会被转换为具有层次结构的BeautifulSoup对象,如果想提取HTML中的内容,只需要知道包围它的标签就可以获得。我们稍后就会介绍。
处理HTTP异常
一旦有任何错误,urlopen都会返回一些错误信息。比如没有找到页面,有可能是404错误,还有500内部服务器错误,这些错误会导致脚本崩溃,我们使用如下代码处理异常:
fromurllib.request
importurlopen from urllib.error
importHTTPError from bs4
importBeautifulSoup
try:html = urlopen("https://www.python.org/")
except HTTPError as e: print(e)
else:
res =BeautifulSoup(html.read(),"html5lib")
print(res.title)
这样就能解决以上的问题。但是如果服务器关了,或者域名输入不对怎么处理?
处理URL异常
若出现网站不能访问,会返回URLError的网络异常,代码做如下处理:
from urllib.request
importurlopen from urllib.error
importHTTPError from urllib.error
importURLError from bs4 import BeautifulSoup
try: html =urlopen("https://www.python.org/")
except HTTPError as e: print(e) exceptURLError:
print("Serverdown or incorrect domain")
else:res = BeautifulSoup(html.read(),"html5lib")
print(res.titles)
接下来,我们需要拿到返回的HTML标签,可能返回的不正常的HTML标签,也可能抓取的页面没有标签,Python会返回一个None对象。
可以用一个简单的if语句来处理。如下代码:
from urllib.request
import urlopen from urllib.error
import HTTPError from urllib.error
import URLError from bs4
import BeautifulSoup
try:html = urlopen("https://www.python.org/")
except HTTPError as e: print(e) exceptURLError: print("Server down or incorrect domain")
else: res =BeautifulSoup(html.read(),"html5lib")
ifres.title is None: print("Tag not found")
else:print(res.title)
看起来很棒,我们的爬虫做得很好。现在,我们就可以抓取整个页面或某个特定的标签了。
但是,如果是更复杂的标签该怎样处理?
使用BeautifulSoup按分类搜索
现在我们尝试通过基于CSS类来抓取一些HTML元素。BeautifulSoup对象有一个名为findAll的函数,它可以根据CSS属性提取或过滤元素。
可以像以下的代码来过滤所有class类为“post-title”的H3元素:
tags= res.findAll("h3", {"class":"post-title"})
接下来我们用for循环来遍历它们。代码如下:
from urllib.request
import urlopen from urllib.error
import HTTPError from urllib.error
import URLError from bs4
import BeautifulSoup
try: html =urlopen("https://likegeeks.com/") except HTTPError as e:
print(e) except URLError: print("Serverdown or incorrect domain")
else: res =BeautifulSoup(html.read(),"html5lib")
tags = res.findAll("h3",{"class": "post-title"})
for tag in tags: print(tag.getText())
以上代码会把所有H3标签中叫做post-title类的内容。
我们使用getText函数来显示标签中的文字,如果不使用将得到包含所有内容的标签。
检查getText的差异
当我们使用getText()函数 ,结果如下:
不使用getText()函数的结果:
BeautifulSoup的全部例子
上面我们看到使用findAll函数过滤标签,下面还有一些方法。
要过滤抓取的HTML中,获取所有span、锚点以及图像标签。
tags= res.findAll("span", "a" "img")
以下代码用来提取所有具有readmorebtn和url类的标签。
tags= res.findAll("a", {"class": ["url","readmorebtn"]})
还可以使用抓取文本参数来取得文本本身。如下:
tags= res.findAll(text="Python Programming Basics withExamples")
findAll函数返回与指定属性相匹配的全部元素。如果只想返回1个元素,可以使用limit参数或使用仅返回第1个元素的find函数。
使用BeautifulSoup找到Nth的子结点
BeautifulSoup对象具有很多强大的功能,如直接获取子元素,如下:
这会获得BeautifulSoup对象上的第一个span元素,然后在此节点下取得所有超链接元素。如果我们想得到第11个节点呢,可以使用如下的选择功能。
tag =res.find("nav", {"id":"site-navigation"}).select("a")[3]
这一行代码将获取id为“site-navigation”的nav元素,然后我们从nav元素中获取第4个超链内容。
BeautifulSoap真是一个功能强大的库。
编译:前端老白
来源:dzone.com