网页数据抓取怎么写(如何用Python爬数据?(一)网页抓取你期待已久的Python网络数据爬虫)
优采云 发布时间: 2021-10-01 13:05网页数据抓取怎么写(如何用Python爬数据?(一)网页抓取你期待已久的Python网络数据爬虫)
如何使用 Python 抓取数据?(一)网页抓取
您期待已久的 Python 网络数据爬虫教程就在这里。本文将向您展示如何从网页中查找有趣的链接和解释性文本,将它们抓取并存储在 Excel 中。
需要
我在公众号后台,经常能收到读者的评论。
很多评论都是来自读者的提问。只要我有时间,我会花时间尝试回答。
但是,有些评论乍一看并不清楚。
例如,以下内容:
一分钟后,他可能觉得不对劲(可能是我想起来了,我用简体中文写了文章),于是又用简体中文发了一遍。
我突然恍然大悟。
这位读者以为我的公众号设置了关键词推送对应的文章功能。所以在阅读了我的其他数据科学教程后,我想看一下“爬虫”这个话题。
抱歉,我当时没有写爬虫。文章。
而且我的公众号暂时没有这种关键词推送。
主要是因为我懒。
这样的消息收到了很多,也能体会到读者的需求。不止一位读者表示对爬虫教程感兴趣。
如前所述,目前主流和合法的网络数据采集方式主要分为三类:
开放数据集下载;
API读取;
爬虫。
前两种方法我已经做了一些介绍,这次就说说爬虫。
概念
很多读者对爬虫的定义有些困惑。我们需要对其进行分析。
维基百科是这样说的:
网络爬虫(英文:web crawler),又称网络蜘蛛(spider),是一种用于自动浏览万维网的网络机器人。它的目的一般是编译一个网络索引。
这是问题。您不打算成为搜索引擎。为什么您对网络爬虫如此热衷?
事实上,很多人所指的网络爬虫与另一个功能“网页抓取”混淆了。
在维基百科上,后者解释如下:
网页抓取、网页采集或网页数据提取是用于从网站提取数据的数据抓取。网络抓取软件可以直接使用超文本传输协议或通过网络浏览器访问万维网。
如果你看到了,即使你用浏览器手动复制数据,也被称为网页抓取。你是不是立刻觉得自己强大了很多?
然而,这个定义还没有结束:
虽然网络抓取可以由软件用户手动完成,但该术语通常是指使用机器人或网络爬虫实现的自动化流程。
换句话说,使用爬虫(或机器人)自动为你完成网页抓取工作,才是你真正想要的。
数据有什么用?
通常,首先将其存储并放置在数据库或电子表格中以供检索或进一步分析。
所以,你真正想要的功能是这样的:
找到链接,获取网页,抓取指定信息,并存储。
这个过程可能会产生回报甚至滚雪球。
您想以自动化的方式完成它。
知道了这一点,您应该停止盯着爬虫。爬虫的开发目的是为搜索引擎索引数据库。您已经在轰炸蚊子以获取一些数据并使用它。
要真正掌握爬虫,需要有很多基础知识。比如HTML、CSS、Javascript、数据结构……
这也是我一直犹豫要不要写爬虫教程的原因。
不过这两天看到王朔编辑的一段话,很有启发:
我喜欢讲一个替代的八分之二定律,就是花 20% 的努力去理解一件事的 80%。
既然我们的目标很明确,那就是从网络上抓取数据。那么你需要掌握的最重要的能力就是如何快速有效地从一个网页链接中抓取你想要的信息。
一旦你掌握了它,你不能说你已经学会了爬行。
但是有了这个基础,您可以比以前更轻松地获取数据。尤其是对于很多“文科生”的应用场景,非常实用。这就是赋权。
而且,更容易进一步了解爬虫的工作原理。
这可以看作是对“第二十八条替代法”的应用。
Python 语言的重要特性之一是它可以使用强大的软件工具包(其中许多由第三方提供)。您只需要编写一个简单的程序即可自动解析网页并抓取数据。
本文向您展示了这个过程。
目标
为了抓取网络数据,我们首先设定一个小目标。
目标不能太复杂。但是要完成它,它应该可以帮助您了解 Web Scraping。
随便选一本我最近出版的小书文章作为爬取的目标。题目是《如何用《玉树智兰》入门数据科学?》。
在这个文章中,我重新整理了一下之前发布的数据科学系列文章。
这篇文章收录许多来自以前教程的标题和相应的链接。例如下图中红色边框包围的部分。
假设你对文章中提到的教程很感兴趣,希望得到这些文章的链接并存入Excel,如下图:
您需要提取和存储非结构化的分散信息(自然语言文本中的链接)。
我们对于它可以做些什么呢?
即使不会编程,也可以通读全文,一一找到这些文章链接,手动复制文章标题和链接分别保存在Excel表格中.
但是,这种手动采集 方法效率不高。
我们使用 Python。
环境
要安装 Python,更简单的方法是安装 Anaconda 包。
请到此网站下载最新版本的 Anaconda。
请选择左侧的Python3.6版本下载安装。
如果您需要具体的分步说明,或者想知道如何在 Windows 平台上安装和运行 Anaconda 命令,请参考我为您准备的视频教程。
安装Anaconda后,请到本网站下载本教程的压缩包。
下载解压后,会在生成的目录(以下简称“demo目录”)中看到如下三个文件。
打开终端,使用cd命令进入demo目录。如果不知道怎么使用,也可以参考视频教程。
我们需要安装一些环境依赖包。
首先执行:
pip 安装 pipenv
这里安装的是一个优秀的Python包管理工具pipenv。
安装完成后,请执行:
管道安装
有没有看到demo目录下Pipfile开头的两个文件?它们是pipenv的配置文件。
pipenv 工具会根据它们自动安装我们需要的所有依赖包。
上图中有一个绿色的进度条,表示要安装的软件数量和实际进度。
安装完成后,按照提示执行:
pipenv 外壳
请在此确认您的计算机上已安装 Google Chrome 浏览器。
我们执行:
jupyter 笔记本
默认浏览器(谷歌浏览器)会打开并启动 Jupyter notebook 界面:
可以直接点击文件列表中的第一个ipynb文件,查看本教程的所有示例代码。
可以一边看教程,一边一一执行这些代码。
但是,我建议的方法是返回主界面并创建一个新的空白 Python 3 notebook。
请按照教程一一输入相应的内容。这可以帮助您更深入地理解代码的含义并更有效地内化您的技能。
准备工作结束,下面开始正式输入代码。
代码
读取网页进行分析抓取,需要用到的软件包是requests_html。我们这里不需要这个包的所有功能,只要读取里面的HTMLSession即可。
从 requests_html 导入 HTMLSession
然后,我们建立一个会话,即让 Python 作为客户端与远程服务器进行对话。
会话 = HTMLSession()
前面提到过,我们计划采集信息的网页是“如何使用“玉树智兰”开始数据科学?“一篇文章。
我们找到它的 URL 并将其存储在 url 变量名称中。
网址 ='#39;
下面的语句使用session的get函数来获取这个链接对应的整个网页。
r = session.get(url)
网页里有什么?
我们告诉 Python 将服务器返回的内容视为 HTML 文件类型。不想看HTML中乱七八糟的格式描述符,只看正文部分。
所以我们执行:
打印(r.html.text)
这是得到的结果:
我们心里清楚。检索到的网页信息正确,内容完整。
好吧,让我们来看看如何接近我们的目标。
我们首先使用简单粗暴的方法尝试获取网页中收录的所有链接。
将返回的内容作为HTML文件类型,我们检查links属性:
r.html.links
这是返回的结果:
这么多链接!
兴奋的?
但是你找到了吗?这里的许多链接似乎不完整。比如第一个结果,只有:
'/'
这是什么?是链接抓取错误吗?
不,这种看起来不像链接的东西叫做相对链接。它是一个相对于我们网页采集所在域名()的路径的链接。
就好像我们在国内邮寄快递包裹,一般填表的时候写“XX省,XX市……”,不需要在前面加国名。只有国际快递,才需要写国名。
但是如果我们想要获取所有可以直接访问的链接呢?
这很简单,只需要一个 Python 语句。
r.html.absolute_links
在这里,我们想要的是一个“绝对”链接,所以我们会得到以下结果:
这次感觉好些了吗?
我们的任务已经完成了吧?链接不都在这里吗?
链接确实在这里,但它们与我们的目标不同吗?
检查它,确实如此。
我们不仅要找到链接,还要找到链接对应的描述文字。是否收录在结果中?
不。
结果列表中的链接是我们所需要的吗?
不。看长度,我们可以感觉到很多链接不是文中描述的其他数据科学文章的URL。
这种直接列出 HTML 文件中所有链接的简单粗暴的方法不适用于此任务。
那么我们应该怎么做呢?
我们必须学会清楚地告诉 Python 我们在寻找什么。这是网络爬行的关键。
想一想,如果你想要一个助手(人类)为你做这件事怎么办?
你会告诉他:
》找到文本中所有可以点击的蓝色文本链接,将文本复制到Excel表格中,然后右键复制对应的链接,复制到Excel表格中。每个链接在Excel中占一行,然后文本和链接各占一个单元格。”
虽然这个操作执行起来比较麻烦,但是小助手在理解之后可以帮你执行。
同样的描述,你试着告诉电脑……对不起,它不明白。
因为你和你的助手看到的网页是这样的。
电脑看到的网页是这样的。
为了让大家看清楚源码,浏览器还特意用颜色来区分不同类型的数据,并对行进行编号。
当数据显示到电脑上时,上述辅助视觉功能不可用。它只能看到字符串。
我能做什么?
仔细观察,你会发现在这些HTML源代码中,在文字和图片链接内容前后都有一些用尖括号括起来的部分,称为“标记”。
所谓HTML就是一种标记语言(HyperText Markup Language)。
商标的作用是什么?它可以将整个文件分解为多个层。
就像你想给某人寄包裹一样,你可以在“省-市-区-街道-社区-门牌”的结构中写一个地址,快递员也可以根据这个地址找到收件人。
同样,我们对网页中的一些特定内容感兴趣,我们可以根据这些标签的结构找出来。
这是否意味着您必须先学习 HTML 和 CSS,然后才能抓取网页内容?
不,我们可以使用工具来帮助您显着简化任务的复杂性。
此工具随 Google Chrome 浏览器一起提供。
我们在示例文章页面点击鼠标右键,在出现的菜单中选择“Check”。
这时,屏幕下方会出现一列。
我们单击此列左上角的按钮(上面标记为红色)。然后将鼠标悬停在第一个文本链接(“玉树之蓝”)上并单击。
此时,你会发现下栏的内容也发生了变化。这个链接对应的源代码放在栏目区域的中间,并高亮显示。
确认该区域是我们要找的链接和文字说明后,我们用鼠标右键选中突出显示的区域,在弹出的菜单中选择Copy -> Copy selector。
找个文本编辑器,执行paste,就可以看到我们复制的内容了。
body> div.note> div.post> div.article> div.show-content> div> p:nth-child(4)> a
这长串标签为电脑指出:请先找到body标签,然后进入管辖区域后找到div.note标签,然后找到...最后找到a标签,这里是内容你正在寻找。
回到我们的 Jupyter Notebook 并使用我们刚刚获得的标签路径来定义变量 sel。
sel ='body> div.note> div.post> div.article> div.show-content> div> p:nth-child(4)> a'
我们让 Python 从返回的内容中找到 sel 对应的位置,并将结果存储在 results 变量中。
结果 = r.html.find(sel)
让我们来看看结果中的内容。
结果
这是结果:
[]
结果是一个仅收录一项的列表。此项收录一个网址,即我们要查找的第一个链接(“玉树知兰”)对应的网址。
但文字描述“《玉树知兰》”去哪儿了?
别着急,我们让Python显示结果数据对应的文字。
结果[0].text
这是输出:
《玉树知兰》
我们还提取了链接:
结果[0].absolute_links
显示的结果是一个集合。
{'#39;}
我们不需要集合,只需要其中的链接字符串。所以我们首先将它转换成一个列表,然后从中提取第一项,即 URL 链接。
列表(结果[0].absolute_links)[0]
这一次,我们终于得到了我们想要的结果:
'#39;
有了处理这第一个环节的经验,你就有了很多信心,对吧?
其他链接无非就是找到标记的路径,然后拍猫和老虎的照片。
但是,如果每次找到链接都需要手动输入这些句子,那就太麻烦了。
这里是编程技巧。一一重复执行的语句。如果工作顺利,我们会尝试将它们合并在一起并制作一个简单的功能。
对于这个函数,只要给出一个选择路径(sel),它就会把它找到的所有描述文本和链接路径返回给我们。
def get_text_link_from_sel(sel):
我的列表 = []
尝试:
结果 = r.html.find(sel)
结果结果:
mytext = result.text
mylink = list(result.absolute_links)[0]
mylist.append((mytext, mylink))
返回我的列表
除了:
返回无
我们来测试一下这个功能。
还是用刚才一样的标记路径(sel),试试吧。
打印(get_text_link_from_sel(sel))
输出如下:
[('玉树芝兰','#39;)]
没问题吧?
好的,让我们尝试第二个链接。
我们还是用刚才的方法,使用下栏左上角的按钮,点击第二个链接。
下面显示的突出显示的内容已更改:
我们仍然使用鼠标右键单击突出显示的部分来复制选择器。
然后我们直接将获取到的标签路径写入到 Jupyter Notebook 中。
sel ='body> div.note> div.post> div.article> div.show-content> div> p:nth-child(6)> a'
用我们刚才编译的函数看看输出结果是什么?
打印(get_text_link_from_sel(sel))
输出如下:
[('如何使用Python作为词云?','#39;)]
经检查,功能没有问题。
下一步是什么?
还是要找第三个链接,按照刚才的方法操作吗?
那么你不妨从全文中手动提取信息,这样可以省去你的麻烦。
我们必须找到一种方法来自动化这个过程。
比较我们只找到两次的标记路径:
body> div.note> div.post> div.article> div.show-content> div> p:nth-child(4)> a
也:
body> div.note> div.post> div.article> div.show-content> div> p:nth-child(6)> a
你找到什么模式了吗?
是的,路径上的所有其他标记都相同,除了倒数第二个标记(“p”)之后冒号之后的内容。
这是我们自动化的关键。
上述两个标签路径中,因为指定了“nth-child”文本段(paragraph,即“p”的意思)来查找标签“a”,所以只返回了一个结果。
如果我们不限制“p”的具体位置信息呢?
让我们试试吧。这次保留标记路径中的所有其他信息,只修改“p”点。
sel ='body> div.note> div.post> div.article> div.show-content> div> p> a'
再次运行我们的函数:
打印(get_text_link_from_sel(sel))
这是输出:
好吧,我们要找的所有内容都在这里。
然而,我们的工作还没有结束。
我们必须将 采集 中的信息输出到 Excel 并保存。
还记得我们常用的数据框工具 Pandas 吗?是时候让它再次展现它的神奇力量了。
将熊猫导入为 pd
只需这行命令,我们就可以将刚才的列表变成一个数据框:
df = pd.DataFrame(get_text_link_from_sel(sel))
我们来看一下数据框的内容:
df
内容还可以,但是我们对标题不满意,所以我们必须用更有意义的列名替换它:
df.columns = ['文本','链接']
查看数据框的内容:
df
好的,现在您可以将捕获的内容输出到 Excel。
Pandas 的内置命令可以将数据框转换为 csv 格式,可以直接在 Excel 中打开查看。
df.to_csv('output.csv', encoding='gbk', index=False)
注意编码需要指定为gbk,否则在Excel中查看默认的utf-8编码可能会出现乱码。
让我们来看看生成的 csv 文件。
很有成就感不是吗?
概括
本文向您展示了使用 Python 自动爬网的基本技巧。希望通过阅读和动手实践,您可以掌握以下知识点:
网络爬虫与网络爬虫的联系和区别;
如何使用pipenv快速搭建指定的Python开发环境并自动安装依赖软件包;
如何利用谷歌浏览器内置的检查功能快速定位感兴趣内容的标记路径;
如何使用requests-html包解析网页并查询获取需要的内容元素;
如何使用 Pandas 数据框工具组织数据并输出到 Excel。
可能你觉得这个文章太简单了,满足不了你的要求。
文章只展示了如何从一个网页中抓取信息,但您必须处理数千个网页。
别担心。
本质上,抓取一个网页与抓取 10,000 个网页相同。
而且,根据我们的示例,您是否已经尝试过抓取链接?
以链接为基础,您可以滚雪球,让 Python 爬虫“爬行”到已解析的链接以进行进一步处理。
以后在实际场景中,你可能要处理一些棘手的问题:
如何将抓取功能扩展到一定范围内的所有网页?
如何抓取Javascript动态网页?
假设你爬取的网站限制了每个IP的访问频率,我该怎么办?
...
这些问题的解决方法,希望在以后的教程中与大家一一分享。
需要注意的是,网络爬虫虽然抓取数据,虽然功能强大,但学习和实践也有一定的门槛。
当您面临数据采集任务时,您应该首先查看此列表:
有没有别人整理过的资料集可以直接下载?
网站你需要的数据有没有API访问和获取方式?
有没有人根据你的需要编了一个自定义爬虫让你直接调用?
如果答案是否定的,则需要自己编写脚本并动员爬虫来抓取它。
为了巩固你所学的知识,请切换到另一个网页,根据我们的代码进行修改,抓取你感兴趣的内容。
如果能记录下自己爬的过程,在评论区与大家分享记录链接就更好了。
因为刻意练习是掌握实践技能的最佳途径,而教学是最好的学习。
祝你好运!
思考
已经解释了本文的主要内容。
这里有一个问题供您思考:
我们解析和存储的链接实际上是重复的:
这不是因为我们的代码有问题,而是在《如何使用“玉树智兰”开始数据科学?“文章中,部分文章被多次引用,所以已抓到重复链接。
但是当您存储时,您可能不想保留重复的链接。
在这种情况下,如何修改代码以确保抓取和保存的链接不重复?
这部分内容我放在文末付费阅读区。如果你愿意支持我的数据科学教程系列的写作,顺便看看你的代码是否比我的更有效率。您只需支付2元(促销期间的价格),阅读这部分内容。
讨论
你对 Python 爬虫感兴趣吗?你在哪些 data采集 任务上使用过它?有没有其他更有效的方式来达到data采集的目的?欢迎留言,与大家分享您的经验和想法,我们一起交流讨论。