


Python培训
400-996-5531
今天要跟大家分享的是一个有趣的且有效的工具——网络爬虫(Web
Scraping)。首先跟大家简短的介绍一下,网络爬虫是一种数据挖掘的方法,可以从网络中抓取海量的数据,并把它存储在本地的系统中。在当前流行的机器学习中也不乏它的应用,它提供了一种搜集数据的手段,毕竟如今时互联网的时代,互联网上有着取之不尽的数据。至于它的其他用途,那就考验你的想象力噜~
现在,我们要做的用爬虫在网上下载几十篇我一直没抽出时间看的 PDF。当然几十篇的话我花上十几分钟也就可以手动下载完了,但是如果当数据多到成千上百了的时候你就可以真切地感受到网络爬虫带给我们的便利了。好了,进入正题!
要建造一只爬虫需要什么工具呢?我们需要用到两个Python的组件:urllib2、BeautifulSoup。其中urllib2在安装Python3的时候本身就安装好了,我们无需安装,但是需要注意的是urllib2在python的导入应该为:
安装BeautifulSoup的方法请看:#/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup
(有什么看不懂的请给我留言)。
接下来我们可以开动啦~首先,用浏览器打开我们今天要“爬”的网站:#/~zwick/Classes/Fall2012_2270/Lectures/
可以按F12进入开发者模式,查看网站的 HTML 格式文件。
接下来着手编辑Python文件,首先当然是导入我们先前说到的两个Python模块:
import urllib.request as urllib2 from bs4 import BeautifulSoup as bfs
大家可以看到,BeautifulSoup 模块的导入与其他模块有些不同,这需要格外注意;其次,as 后面的名字是由自己取的,目的是简化模块名,不然你想想每次要用到 BeautifulSoup 模块都得输入那么多个字母那不得累死!所以我后面也将称它为 bfs,哈哈哈哈。下一步是将我们要爬取的网站指定、并发起请求:
# Specify the url we are going to scrap. index = "#/" \ "~zwick/Classes/Fall2012_2270/Lectures/" # Query the website and return the html.page = urllib2.urlopen(index)
这里大家也可以揣测到urllib2.urlopen()函数便是用来发起请求的,并且它会返回一个 HTML ,我们将它存在 page 中。接下来我们需要将这个 HTML 格式的内容解析成方便我们使用的 bfs “格式”(暂且这么称呼它吧~):
# Parse the html. soup = bfs(page,"html5lib")
现在我们可以先看一下我们当前的效果是怎样的,通过输入:
print(soup.prettify())
我们可以得到当前获得页面的 HTML 代码(由于篇幅过大仅截取一部分):
首先,<a>标记中是超链接的意思,“href” 则是该超链接的地址,但是从次片段我们可以发现,该“href”并不代表着我们要爬取的页面的地址,正确的地址应该加上我们前面的主页地址才完整:
”#/~zwick/Classes/Fall2012_2270/Lectures/“ + “href”中的值
接着,我们需要得到的是所有带有标签<a>的项,因为我们需要得到每个 PDF 文件的链接才能实现下载:
all_links = soup.find_all("a")
emmmmmm....没错,就这简单的一句。
得到标签<a>之后,要考虑的就是如何得到<a>中的属性“href”,幸好,bsf 早就为我们准备好了。由于是对于每一<a>标签我们都需要获取其属性“href”,因此这里我们用一个 for 循环来解决这个问题:
for link in all_links:
downlink = link.get("href")
if "Lecture" not in downlink:
continue
f = open("Linear algebra/"+downlink, "wb")
f.write(urllib2.urlopen(index + downlink).read())
print(downlink, "downloaded!")
f.close()
嗯,这里我把剩下所有代码都给出来了....总的代码也不过24行,这就是我为什么不想一个一个 PDF 去下载的原因~
先看第一行
for link in all_links:
指的是在每一次循环中用 link 来存储 all_links 的一个值,直到遍历了 all_links 中所有的值才结束。
再看
downlink = link.get("href")
if "Lecture" not in downlink:
continue
这里我们新建了一个变量 downlink ,由于 link 中存的是一个 <a> 标签,所以我们通过方法 get(“href”) 可以得到例如 <a href="Lecture1.pdf">中的 “Lecture1.pdf” 并存入downlink ,其类型是 String 字符串。
接下来要考虑的问题是如何从我们获取的链接中把 PDF 下载下来呢?
第一我们要面对一个问题,如何筛选出哪些是我们需要的下载链接哪些不是呢,比如说对于网站中的 Name 、Last modified等并不是我们需要的链接,所以我们需要用一个 if 语句把这些过滤掉。这里我用的是对于那些属性 “href” 中不含 “Lecture” 的均无需理睬,使用一句 continue 使循环回到头部执行,而忽略循环后面的部分。
过滤掉那些无用的链接之后对于得到的链接该怎么做呢?
f = open("Linear algebra/"+downlink, "wb")
f.write(urllib2.urlopen(index + downlink).read()) print(downlink, "downloaded!")
f.close()
首先我们需要在运行这段程序前,在工程目录下新建一个文件夹名为“Linear algebra”(因为我们的这些 PDF 正是我没学好的线性代数)。再看这几行代码执行的逻辑为:
以二进制写入的格式打开文件 “Linear algebra/” + downlink (是不是有点好奇为啥用上了 + 号,因为downlink也是一个字符串,连接两个字符串我们用加号 + 来实现),例如下载 “Lecture1.pdf” 时,downlink = “Lecture1.pdf” 然后连在一起文件的路径正是“Linear algebra/Lecture1.pdf”。有的同学可能又会好奇明明还没下载下来我怎么打开这个文件呢?嗯,如果这个文件不存在的时候,Python会帮我们自动创建~
urllib2.urlope(index + downlink)解决了我们之前说到的,超链接<a href="Lecture1.pdf"> 中“Lecture1.pdf” 不是正确的网址的问题,正确的网址应该是字符串 index 连上 downlink。(例如:#/~zwick/Classes/Fall2012_2270/Lectures/Lecture1.pdf),再运用read() 方法得到 pdf 文件的二进制码,这时候用写入方法write() 将文件写入我们指定的名称和路径即可。
将该文件关闭。
通过几十个循环我们便可以将文件全部下载下来啦~硕果累累呀
最后给出文章中完整的代码(需要文件的同学后台回复scrapPDF):
import urllib.request as urllib2 from bs4 import BeautifulSoup as bfs # Specify the url we are going to scrap. index = "#/" \
"~zwick/Classes/Fall2012_2270/Lectures/" # Query the website and return the html. page = urllib2.urlopen(index) # Parse the html. soup = bfs(page,"html5lib")
all_links = soup.find_all("a") for link in all_links:
downlink = link.get("href")
if "Lecture" not in downlink:
continue
f = open("Linear algebra/"+downlink, "wb")
f.write(urllib2.urlopen(index + downlink).read())
print(downlink, "downloaded!")
f.close()
经过这篇文章我们学会了怎么简单的在网上抓取一些我们感兴趣的内容,当然网络爬虫的用途以及难度远不止如此,面对一些有相应保护措施的网站我们要做的就更多了,再后面的推文中我也会跟大家分享一些有趣的方法并做一些有趣的内容。
填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有