使用 Python 从 Web 上抓取媒体内容
介绍
大多数人开始从网站中提取数据时,都是从 HTML 中提取文本。然而,还有另一种丰富的信息来源,即多媒体。这种“基于二进制”的数据集合包括图像、视频、音频和特殊格式的文档(如电子表格和 pdf 文件),以及压缩数据等。本指南将向您展示如何抓取这些类型的文件,并了解远程 Web 服务器如何传达它发送给抓取客户端的文件类型。
要求
在本指南中,我们将使用 Python 的“Requests”库来获取数据,并使用“Lxml”库来解析我们下载的 HTML。这些库使用起来非常简单,适用于大多数网页抓取目的。我们还将使用“Pafy”和“Youtube-dl”库来帮助从 Youtube 抓取流媒体视频文件。
先决条件:
一般来说,一旦正确安装了 Python 3,您就可以使用“PIP”实用程序下载 Lxml 和 Requests:
pip install requests
pip install lxml
pip install pafy
pip install youtube-dl
如果未安装Pip,你可以在此处下载并安装
对于简单的网页抓取,像 Microsoft Visual Code(免费使用和下载)这样的交互式编辑器是一个不错的选择,它适用于 Windows、Linux 和 Mac。
入门 - 抓取简单媒体文件
大多数刚开始进行网页抓取的开发人员遇到的第一个媒体文件是图像文件格式。图像可以在网页中以多种方式呈现给我们,但一般来说,它们以简单的基于 URL 的链接形式提供,这些链接可以是绝对的,也可以是相对的。绝对链接包含我们下载文件所需的所有内容,并在 HTML 代码中显示如下:
http://www.howtowebscrape.com/examples/images/test1.jpg
另一方面,相对链接通常仅包含相对于您调用的网页的图像路径,这有时会导致混淆:
examples/media/images/test1.jpg
此相对链接与绝对链接相同,只要您在主域路径中添加用于调用包含相对图像的 HTML 页面即可。例如,我们调用网页:
http://www.howtowebscrape.com/examples/media1.html
其中包含 HTML 标签:
<img src=”/media/images/test1.jpg”>
在这种情况下,我们将采用从中接收 HTML 的主路径,并将其添加到前面以创建完整正确的可调用链接。
下图有助于直观地解释这一概念:
无论图像路径以何种方式呈现给我们,我们都需要有一个完整有效的链接才能下载文件。
从网页中提取媒体链接
除非我们已经知道要下载的媒体,否则我们通常必须下载网页并对其进行解析才能找到所需的链接。要了解有关下载和使用 HTML 以及抓取和解析第一个网页的更多信息,请参阅我之前的指南《使用 Python 抓取您的第一个网页》。
下载网页和获取媒体目标链接所需的基本代码如下所示,并附有内联注释来解释每一行代码。
要下载页面,我们只需要要求请求库“获取”它,因此我们为示例声明一个名为“page”的变量,并将对“get”的调用的结果加载到这个变量中。
from lxml import html, etree
import requests
# Get the original webpage html content
webpageLink = 'http://www.howtowebscrape.com/examples/simplescrape1.html'
page = requests.get(webpageLink)
# convert the data received into searchable HTML
extractedHtml = html.fromstring(page.content)
# use an XPath query to find the image link (the 'src' attribute of the 'img' tag).
imageSrc = extractedHtml.xpath("//img/@src") # in our example, result = ‘/images/GrokkingAlgorithms.jpg’
# strip off the actual *page* being called as we only want to base url
imageDomain = webpageLink.rsplit('/', 1) # in our example, result = http://www.howtowebscrape.com/examples/
现在我们有了图片的链接 URL,我们可以测试它是相对链接还是绝对链接。一种简单的检查方法是查看提取的链接是否存在“http”,这表明正在使用“超文本传输协议”。
# test if this is an absolute link or relative
if imageSrc[0].startswith("http"):
# start with http, therefore take this as the full link
imageLink = imageSrc[0]
else:
# does not start with http, therefore construct the full url from the base url plus the absolute image link
imageLink = str(imageDomain[0]) + str(imageSrc[0])
在此阶段,我们现在有一个完全合格的 URL 或网络链接,我们可以使用它从网络服务器本身下载媒体。我们将首先提取链接的文件名部分,然后使用“requests.get”从网络服务器获取文件,最后我们可以将收到的数据保存到文件中。
# extract file name from link
filename = imageLink.split("/")[-1]
# download image using GET
rawImage = requests.get(imageLink, stream=True)
# save the image received into the file
with open(filename, 'wb') as fd:
for chunk in rawImage.iter_content(chunk_size=1024):
fd.write(chunk)
抓取多种类型的媒体
一旦我们知道了所需文件的绝对网络链接,我们就可以使用完全相同的概念来下载任何类型的二进制文件。为了提高效率,我们可以将主要下载代码构建为函数调用。
def downloadFile(AFileName):
# extract file name from AFileName
filename = AFileName.split("/")[-1]
# download image using GET
rawImage = requests.get(AFileName, stream=True)
# save the image recieved into the file
with open(filename, 'wb') as fd:
for chunk in rawImage.iter_content(chunk_size=1024):
fd.write(chunk)
return
如您所见,该函数的功能与我们之前编写的代码完全相同,但包装在一个函数中,以便我们可以轻松地重复使用它。为了演示代码在各种媒体类型上运行,我们可以针对文档、pdf、音频和视频等媒体类型调用该函数。
downloadFile("http://www.howtowebscrape.com/examples/media/images/BigRabbit.mp4")
downloadFile("http://www.howtowebscrape.com/examples/media/images/Clapping.mp3")
downloadFile("http://www.howtowebscrape.com/examples/media/images/SampleSlides.pptx")
downloadFile("http://www.howtowebscrape.com/examples/media/images/SampleZip.zip")
使用内容属性
有时,您可以下载文件,但文件的名称或文件扩展名可能与文件本身的内容不匹配。在这些情况下,我们可以检查 Web 服务器发送的元数据,并使用它来帮助我们生成正确的文件扩展名类型。我们获取此信息的方式是在建立连接后检查请求对象的 headers 属性:
rawImage = requests.get(imageLink, stream=True)
print(rawImage.headers)
这将产生如下 JSON 输出:
{'Content-Type': 'image/jpeg', 'Last-Modified': 'Tue, 07 May 2019 18:57:12 GMT', 'Accept-Ranges': 'bytes', 'ETag': '"1eae29ae65d51:0"', 'Server': 'Microsoft-IIS/8.5', 'X-Powered-By': 'ASP.NET', 'Date': 'Tue, 07 May 2019 22:29:10 GMT', 'Content-Length': '50424'}
从这里,我们可以获得媒体类型(image/jpeg)和文件大小。
从 Youtube 抓取流媒体视频
媒体并不总是像前面的例子那样清晰地呈现给我们。要下载 Youtube 视频,我们可以使用“pafy”库。Youtube 视频链接可能难以识别 - pafy 库可以帮助我们解决这个问题。除了识别正确的下载链接外,该库还允许我们访问有关视频的其他信息,例如作者、大小、可用格式等。
下载Youtube文件只需要几行代码:
# Download the Pluralsight 'we are one' video
# url of video
url = "https://www.youtube.com/watch?v=TgRwoBgPM0o"
# create video object
video = pafy.new(url)
# extract information about best resolution video available
bestResolutionVideo = video.getbest()
# download the video
bestResolutionVideo.download()
结论
网络抓取是一项重要的技能,尤其是对于从事数据、商业智能和数据科学工作的开发人员来说。本指南简要介绍了如何从网络上抓取不同类型的媒体。如果您想了解有关该主题的更多信息,请考虑 Pluralsight 提供的以下课程:
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~