如何用Python爬数据?(一)网页抓取
优采云 发布时间: 2020-08-09 22:46你期盼已久的Python网路数据爬虫教程来了。本文为你演示怎么从网页里找到感兴趣的链接和说明文字,抓取并储存到Excel。
(由于微信公众号外部链接的限制,文中的部份链接可能难以正确打开。如有须要,请点击文末的“阅读原文”按钮,访问可以正常显示外链的版本。)
需求
我在公众号后台,经常可以收到读者的留言。
很多留言,是读者的疑惑。只要有时间,我就会抽空尝试解答。
但是有的留言,乍看上去就不明所以了。
例如下边这个:
一分钟后,他可能认为不妥(大概由于想起来,我用简体字写文章),于是又用繁体发了一遍。
我恍然大悟。
这位读者以为我的公众号设置了关键词推送对应文章功能。所以看了我的其他数据科学教程后,想看“爬虫”专题。
不好意思,当时我还没有写爬虫文章。
而且,我的公众号暂时也没有设置这些关键词推送。
主要是因为我懒。
这样的消息接收得多了,我也能揣度到读者的需求。不止一个读者抒发出对爬虫教程的兴趣。
之前提过,目前主流而合法的网路数据搜集技巧,主要分为3类:
前两种方式,我都早已做过一些介绍,这次谈谈爬虫。
概念
许多读者对爬虫的定义,有些混淆。咱们有必要辨析一下。
维基百科是这么说的:
网络爬虫(英语:web crawler),也叫网路蜘蛛(spider),是一种拿来手动浏览万维网的网路机器人。其目的通常为编修网路索引。
这问题就来了,你又不准备做搜索引擎,为什么对网路爬虫这么热心呢?
其实,许多人口中所说的爬虫(web crawler),跟另外一种功能“网页抓取”(web scraping)搞混了。
维基百科上,对于前者这样解释:
Web scraping, web harvesting, or web data extraction is data scraping used for extracting data from websites. Web scraping software may access the World Wide Web directly using the Hypertext Transfer Protocol, or through a web browser.
看到没有,即便你用浏览器自动拷贝数据出来,也称作网页抓取(web scraping)。是不是立即认为自己强悍了好多?
但是,这定义还没完:
While web scraping can be done manually by a software user, the term typically refers to automate processes implemented using a bot or web crawler.
也就是说,用爬虫(或者机器人)自动替你完成网页抓取工作,才是你真正想要的。
数据抓出来干哪些呢?
一般是先储存上去,放到数据库或则电子表格中,以备检索或则进一步剖析使用。
所以,你真正想要的功能是这样的:
找到链接,获得Web页面,抓取指定信息,存储。
这个过程有可能会往复循环,甚至是滚雪球。
你希望用自动化的方法来完成它。
了解了这一点,你就不要老盯住爬虫不放了。爬虫研发下来,其实是为了给搜索引擎编制索引数据库使用的。你为了抓取点儿数据用来使用,已经是大炮轰虫子了。
要真正把握爬虫,你须要具备不少基础知识。例如HTML, CSS, Javascript, 数据结构……
这也是为何我仍然迟疑着没有写爬虫教程的诱因。
不过这三天,看到王烁主编的一段话,很有启发:
我喜欢讲一个另类二八定律,就是付出两成努力,了解一件事的八成。
既然我们的目标太明晰,就是要从网页抓取数据。那么你须要把握的最重要能力,是领到一个网页链接后,如何从中快捷有效地抓取自己想要的信息。
掌握了它,你还不能说自己早已学会了爬虫。
但有了这个基础,你能够比之前更轻松获取数据了。特别是对“文科生”的好多应用场景来说,非常有用。这就是赋能。
而且,再进一步深入理解爬虫的工作原理,也显得轻松许多。
这也算“另类二八定律”的一个应用吧。
Python语言的重要特色之一,就是可以借助强悍的软件工具包(许多都是第三方提供)。你只须要编撰简单的程序,就能手动解析网页,抓取数据。
本文给你演示这一过程。
目标
要抓取网页数据,我们先制定一个小目标。
目标不能很复杂。但是完成它,应该对你理解抓取(Web Scraping)有帮助。
就选择我近来发布的一篇简书文章作为抓取对象好了。题目称作《如何用《玉树芝兰》入门数据科学?》。
这篇文章里,我把之前的发布的数据科学系列文章做了重新组织和串讲。
文中收录好多之前教程的标题和对应链接。例如下图蓝色边框圈上去的部份。
假设你对文中提及教程都太感兴趣,希望获得这种文章的链接,并且储存到Excel里,就像下边这个样子:
你须要把非结构化的分散信息(自然语言文本中的链接),专门提取整理,并且储存出来。
该如何办呢?
即便不会编程,你也可以全文研读,逐个去找这种文章链接,手动把文章标题、链接都分别拷贝出来,存到Excel表上面。
但是,这种手工采集方法没有效率。
我们用Python。
环境
要装Python,比较省事的办法是安装Anaconda套装。
请到这个网址下载Anaconda的最新版本。
请选择两侧的 Python 3.6 版本下载安装。
如果你须要具体的步骤指导,或者想知道Windows平台怎么安装并运行Anaconda命令,请参考我为你打算的视频教程。
安装好Anaconda以后,请到这个网址下载本教程配套的压缩包。
下载后解压,你会在生成的目录(下称“演示目录”)里面听到以下三个文件。
打开终端,用cd命令步入该演示目录。如果你不了解具体使用方式,也可以参考视频教程。
我们须要安装一些环境依赖包。
首先执行:
pip install pipenv<br />
这里安装的,是一个优秀的 Python 软件包管理工具 pipenv 。
安装后,请执行:
pipenv install<br />
看到演示目录下两个Pipfile开头的文件了吗?它们就是 pipenv 的设置文档。
pipenv 工具会根据它们,自动为我们安装所须要的全部依赖软件包。
上图上面有个红色的进度条,提示所需安装软件数目和实际进度。
装好后,根据提示我们执行:
pipenv shell<br />
此处请确认你的笔记本上早已安装了 Google Chrome 浏览器。
我们执行:
jupyter notebook<br />
默认浏览器(Google Chrome)会开启,并启动 Jupyter 笔记本界面:
你可以直接点击文件列表中的第一项ipynb文件,可以看见本教程的全部示例代码。
你可以一边看教程的讲解,一边依次执行这种代码。
但是,我建议的方式,是回到主界面下,新建一个新的空白 Python 3 笔记本。
请跟随教程,一个个字符输入相应的内容。这可以帮助你更为深刻地理解代码的含意,更高效地把技能内化。
准备工作结束,下面我们开始即将输入代码。
代码
读入网页加以解析抓取,需要用到的软件包是 requests_html 。我们此处并不需要这个软件包的全部功能,只读入其中的 HTMLSession 就可以。
from requests_html import HTMLSession<br />
然后,我们构建一个会话(session),即使Python作为一个客户端,和远端服务器攀谈。
session = HTMLSession()<br />
前面说了,我们准备采集信息的网页,是《如何用《玉树芝兰》入门数据科学?》一文。
我们找到它的网址,存储到url变量名中。
url = 'https://www.jianshu.com/p/85f4624485b9'<br />
下面的句子,利用 session 的 get 功能,把这个链接对应的网页整个儿取回去。
r = session.get(url)<br />
网页上面都有哪些内容呢?
我们告诉Python,请把服务器传回去的内容当成HTML文件类型处理。我不想要看HTML上面这些乱七八糟的格式描述符,只看文字部份。
于是我们执行:
print(r.html.text)<br />
这就是获得的结果了:
我们心里有数了。取回去的网页信息是正确的,内容是完整的。
好了,我们来瞧瞧如何趋近自己的目标吧。
我们先用简单粗暴的方式,尝试获得网页中收录的全部链接。
把返回的内容作为HTML文件类型,我们查看 links 属性:
r.html.links<br />
这是返回的结果:
这么多链接啊!
很兴奋吧?
不过,你发觉没有?这里许多链接,看似都不完全。例如第一条结果,只有:
'/'<br />
这是哪些东西?是不是链接抓取错误啊?
不是,这种看着不象链接的东西,叫做相对链接。它是某个链接,相对于我们采集的网页所在域名()的路径。
这就好象我们在国外寄送快件包裹,填单子的时侯通常会写“XX市XX区……”,前面不需要加上国家名称。只有国际快件,才须要写上国名。
但是假如我们希望获得全部可以直接访问的链接,怎么办呢?
很容易,也只须要一条 Python 语句。
r.html.absolute_links<br />
这里,我们要的是“绝对”链接,于是我们都会获得下边的结果:
这回看着是不是就舒服多了?
我们的任务已经完成了吧?链接不是都在这里吗?
链接确实都在这里了,可是跟我们的目标是不是有区别呢?
检查一下,确实有。
我们不光要找到链接,还得找到链接对应的描述文字呢,结果里收录吗?
没有。
结果列表中的链接,都是我们须要的吗?
不是。看宽度,我们才能觉得出许多链接并不是文中描述其他数据科学文章的网址。
这种简单粗鲁直接列举HTML文件中所有链接的方式,对本任务行不通。
那么我们该如何办?
我们得学会跟 Python 说清楚我们要找的东西。这是网页抓取的关键。
想想看,如果你想使助手(人类)帮你做这事儿,怎么办?
你会告诉他:
“寻找正文中全部可以点击的黑色文字链接,拷贝文字到Excel表格,然后右键复制对应的链接,也拷贝到Excel表格。每个链接在Excel占一行,文字和链接各占一个单元格。”
虽然这个操作执行上去麻烦,但是助手听懂后,就能帮你执行。
同样的描述,你试试说给笔记本听……不好意思,它不理解。
因为你和助手看见的网页,是这个样子的。
电脑听到的网页,是这个样子的。
为了使你看得清楚源代码,浏览器还特意对不同类型的数据用了颜色分辨,对行做了编号。
数据显示给笔记本时,上述辅助可视功能是没有的。它只能看到一串串字符。
那可怎么办?
仔细观察,你会发觉这种HTML源代码上面,文字、图片链接内容前后,都会有一些被尖括弧括上去的部份,这就叫做“标记”。
所谓HTML,就是一种标记语言(超文本标记语言,HyperText Markup Language)。
标记的作用是哪些?它可以把整个的文件分解出层次来。