在我们学习资料分析的过程中,很常会被拿到各种各样的资料集来作为例子,不过有的时候我们也会希望有一些比较不同或是比较实际特定遇到的资料来进行分析,那这个时候具备有自己可以获得资料的能力就很方便了,因此今天会来简单介绍一下基本的爬虫概念,并以自动爬取一个gif梗图网站的梗图下载下来为例子吧(私心XD)
网页,一个对我们日常生活中非常熟悉的东西(还是其实现在年轻人都只用app了吗?)
不论是用来看新闻、看股票,亦或是拿来看梗图都非常的方便,而这也自然成为了一个很适合作为资料分析来源的地方,不然每次都用那种竞赛或是实验室所提供的资料不觉得有点无趣吗~
那网页是什麽呢
网页其实和程序一样,就只是一堆文字而已
不过就像不同的程序语言有不同的语法,网页页面实际上也是遵循着特定的规则来记录的内容,一般都是遵循 html(HyperText Markup Language) 的形式来记录内容。
以我今天打开一个梗图网站为例,我看到了不同的区块、文字、影片、连结...等内容,而这些内容又有着不同的样子(例如不同的字体大小)或是不同的功能(例如某区块点了之後会跳转),那这些其实都是依靠我们的浏览器帮我们把网站的html内容解析之後转换成适合人类阅读和操作的样子。
那既然我们说网页只是一串文字,那要怎麽看到这串文字长得怎样呢?
我们只要在网页的空白处按下「检视网页原始码」(Chrome)或是「检视页面来源」(Edge)就可以看到这个页面的原始html是长得怎样了。
那既然我们不是电脑,在没有什麽经验的时候面对这麽大量的原始码内容当然会不太方便,所以这个时候可以使用浏览器内建的开发工具来直接找到某个页面元素相关的html内容。
左边的页面会随着我们右边滑鼠指到不同的区块而产生对应的高亮以方便我们检视。
对於第一次接触到网页架构的读者也许会觉得它好像很复杂,不过我们作为一个只是要它的资料而不是要知道它是怎麽建立起来的角度,我们只需要知道
网页元素,就是一堆
<类型 一些属性>一些内容</类型>
的东西包来包去而已
像是这边的gif,我们发现他的元素内容是
<video autoplay="" muted="" loop="" poster="https://media.giphy.com/media/W0yN0GEVU2eHUeYlYQ/giphy.gif">
<source src="https://media.giphy.com/media/W0yN0GEVU2eHUeYlYQ/giphy.mp4" type="video/mp4">
</video>
因此它看起来就是一个有一些各种(不用管)属性的video
而已
说完网页的基本架构,那来讲一下爬虫的定位
爬虫其实就是用各种语言的程序来代替我们和浏览器,用来取得网页的内容
而同时因为程序很适合处理大量的资料,因此拿来做一些自动化的操作就很方便
我们这边以python中最基本的request
套件来说明要如何取得网页
import requests
url = "https://www.gif-vif.com/you-are-a-wizard-doggo"
res = requests.get(url) # 取得回应
res
输出:
<Response [200]>
这边的200表示正常收到内容,而如果是
那既然爬虫是代替浏览器,我们刚刚看到的原始码又在哪边呢?
# 显示原始码
print(res.text)
那我们有了原始码之後,可是我们不像是在用浏览器一样有滑鼠可以去选择,那要如何找到这些资料呢?
如果你想到的是可以用我们之前讲过的字串处理技巧和正规搜寻的话,那先很感谢你有认真在看我这写的不是很精练的文字。但其实既然爬虫资料处理是一个很基本的需求的话,那通常python就会有对应的套件,我们这边以最常见的BeautifulSoup
为例子
人生苦短,我用python
——某位大前辈
from bs4 import BeautifulSoup
soup = BeautifulSoup(res.text, 'lxml') # lxml是解析方式
soup
vidio_elements = soup.find_all("video")
vidio_elements
那发现我们所需要的gif连结就在这个地方,因此剩下就是把它取出来
gif_url = vidio_elements[0].get("poster")
gif_url
输出:
'https://media.giphy.com/media/W0yN0GEVU2eHUeYlYQ/giphy.gif'
gif = requests.get(gif_url) # 一样再取得一次网页
with open("sample.gif", "wb") as f: # 用二进制方式写入档案
f.write(gif.content) # content表示内容
那执行之後应该就会看到它在这份程序的同一个资料夹了
我们可以用同样的原理,将下一页的url也取出来,然後重复呼叫就可以自动下载档案了~
def get_gif(url):
title = url.split("/")[-1] # 取得url结尾作为标题
print(f"getting gif {title}")
res = requests.get(url) # 取得回应
# 使用BeautifulSoup解析内容
soup = BeautifulSoup(res.text, 'lxml')
vidio_elements = soup.find_all("video")
gif_url = vidio_elements[0].get("poster")
# 下载gif
gif = requests.get(gif_url)
with open(f"{title}.gif", "wb") as f:
f.write(gif.content)
# 寻找下一个url
next_url = soup.find(id="share_and_next").find_all("a")[-1].get("href")
return next_url
if __name__ == "__main__":
url = "https://www.gif-vif.com/you-are-a-wizard-doggo"
for i in range(10):
url = get_gif(url)
好几天没有打的这麽长了,因为想说只提最基本必要的东西,但又想举个实际的例子所以还是会有一点不同的步骤要说明。不过如果这边的可以看懂之後,再配合一点基本的html不同元素的知识,应该就可以做出一些非常基本的爬虫了~
<<: Re: 新手让网页 act 起来: Day28 - Error boundary
前面有提到安装 TailwindCSS 推荐使用 PostCSS,前面练习的都是没有相依 Post...
前面只用linux 的指令来拍图 现在用Python了 from time import sleep...
CDN 这个名词在前面的篇章应该出现过蛮多次的,一直感到困惑的朋友们不用担心,今天终於要来好好介绍...
哈罗,我是Eason,欢迎来到我的 「WordPress 再进化,用 Next.js 拆分前端,实现...
前言 JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用...