Python黑科技
Web Scraper (一)爬虫与甲鱼汤
前言
相信各位大佬一定都或多或少接触过网络爬虫了。这次内容将分两部分简略介绍一些爬虫的方法和技巧,让新人也能快速上手。若你已经是爬虫大佬,欢迎提出宝贵意见来完善内容。
网络爬虫,“爬”的是什么?
Web Scraper的应用就在于爬取网站的内容。比如说你想让你的程序获取wikipedia一个词条的全部内容,除了复制粘贴外最高效的做法就是用爬虫把词条爬下来。这是怎么做到的呢?
几乎所有的网页都是用某种"markup language",“标记语言”所写。标记语言的意思就是网站的框架结构及(部分)内容都由“标记”所决定。比如说,这是一行html (HyperText Markup Language)代码:
Hello World!
这行代码告诉浏览器:在这里创建一个段落,里面的文字是"Hello World!". 于是,如果你把有这行代码的文件保存为.html然后双击打开,你就会发现你的默认浏览器弹出了一个网页,上面有一行"Hello World!".
对就是这么简单。这里的
是一个"tag",他用来告诉浏览器要怎么对待他中间的文本。
代表开始,
里加个斜杠代表这行语句结束。常见的tag还有, 等等。。
这玩意我小学就知道了,然后呢?
网络爬虫就是运用markup language的特征,用tag以及"attribute"来判断所需要爬取的内容。至于attribute是什么,attribute就是某个tag的特殊属性。比如如果你想把一个
tag放进某个class里,可以这样写:
。这里的"class"就是一个attribute. 那么问题就简单了。如果我想爬取这个
tag里的文字,我可以这样说:
“给我找到那个有"MouGeClass” class属性的p标签,然后把它里面的文本拽出来。”
这该怎么办到?甲鱼汤。
BeautifulSoup4
BeautifulSoup是一个Python library。它的功能强大到可以让我们轻松用寥寥几行代码完成网页的爬取工作。至于为什么叫甲鱼汤,是因为其命名来源于《爱丽丝梦游仙境》。有兴趣的朋友可以去了解一下。
那么as always,第一步
pip install BeautifulSoup4
注意,一定是BeautifulSoup"4",因为这个版本有对Python 3最好的支持。
贯彻OOP的理念:
from bs4 import BeautifulSoup
soup = BeautifulSoup(...)
若想创建一个BeautifulSoup对象,我们需要提供两个参数。其一是一个html string,也就是网页的源码,其二是用来解析源码的"parser"。这里对此不过多介绍,使用Python自带的"html.parer"即可。
等下。网页的源码?我怎么好像已经学过怎么搞了。
Alex Thornton在32里教过如何使用urlopen函数来获取html文本。没有上过32的小伙伴也不用着急,因为这个东西只要两行代码:
from urllib.request import urlopen
html = urlopen("MouGeURL")
现在我们就可以初始化BeautifulSoup对象了。因为html是一个HTTPResponse对象,我们用read方法来获取文本内容;
soup = BeautifulSoup(html.read(), "html.parser")
这里不需要把bytes转换为string, BeautifulSoup可以自动识别。
那么这个"soup"可以干吗呢?假设我们之前写的那行代码是某个网站的第一句带有
tag的代码,那么
print(soup.p)
就会把这行代码原原本本地print出来。
等等,两个问题。只要在soup后面加那个tag就行了?还有为啥是把这行代码print出来,我们要的不是
和
中间的文本吗?
第一个问题:dei. soup.p会让soup自动搜索第一个
tag,所以哪怕这个网页的代码是
,soup.p也能输出一样的结果。同时,正如你所想的一样,soup.div.p在上面的情形也一样适用。
第二个问题:若是想要获取文本,我们得“获取文本”。这样写:
print(soup.p.get_text())
.get_text()方法,正如其名,将tag都strip掉,只保留其中的文本。
所以,print(soup.p)的结果是
Hello World!
,而print(soup.p.get_text())的结果是Hello World!.
如果这个网页里没有带有
tag的语句,怎么办?
想象一下,如果你的scraper里有一个庞大的loop,然后这句soup.p是其中一行代码。如果这行代码出问题了,那么这个loop就会终止,你想要的内容就不会被完整得爬下来。
所以,遵从Alex Thornton教会我们的设计原则,我们得考虑exception。
实际上,若是找不到
tag,soup.p这行语句并不会出太大问题,因为它会return None.问题就在于,如果我们写的是soup.p.QiTaDongXi, 那么就成了AttributeError.所以这是需要注意的一点。
我们还要注意的是,(32可能已经讲过了),urlopen可能没有找到你给他的url,以及这个url的服务器出现了问题。我们可以直接在正段代码外面加上try except。如果你想细分catch的是哪个exception,可以用urllib.error里的HttpError和URLError。此处就不啰嗦了。
结尾
下期我们将简略介绍BeautifulSoup的其他用法以及另外一个和爬虫有关的library,请关注CUCS公众号来获取最新动态。
CUCS宣传部 张新宸(文案兼排版)
领取专属 10元无门槛券
私享最新 技术干货