爬虫实战:爬掉 MBA 智库中的百科
目标
首先说下目标:Spider 以下可以链接到的所有百科文本。
地址:https://wiki.mbalib.com/wiki/MBA%E6%99%BA%E5%BA%93%E7%99%BE%E7%A7%91:%E5%88%86%E7%B1%BB%E7%B4%A2%E5%BC%95
一些初始化
由于使用类,所以要进行一些初始化:
def __init__(self):self.wikiURL = 'https://wiki.mbalib.com'self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/51.0.2704.63 Safari/537.36'}self.hadGone = {} # 用来保存已经爬取过的网页
从主页面开始说起
简单分析
首先需要明确一点:该页面下可能存在许多重复的网页。
为了防止漏爬,我们选择遍历所有索引;同时,为了提高效率和防止重复爬取,使用一个集合来存储已经爬过的 url,劲儿保证每次遍历的都是未曾经走过的网页。
例如:对于“金融理论”下的网页而言,存在以下四种子类(见下图),因此该随后的“国际收支调节理论”,“货币理论”,“银行理论”等网页无需重复爬取。
网页格式
在该网页内使用开发者模式,观察其格式:
注意到,索引界面都是用<p>
表示的,我们可以一路 next 到底了。
现在,我们的任务是:将“金融百科”目录下的所有 href 属性爬取下来,并以列表的形式存储。
获取 href
吐槽:MBA中总共有 6 大类,竟然用style
标签来区分。
代码:
def get_home_html(self): # 用来爬取首页所需的索引url = "https://wiki.mbalib.com/wiki/MBA%E6%99%BA%E5%BA%93%E7%99%BE%E7%A7%91:%E5%88%86%E7%B1%BB%E7%B4%A2%E5%BC%95#.E9.87.91.E8.9E.8D.E7.99.BE.E7.A7.91"r = requests.get(url, headers=self.headers)soup = BeautifulSoup(r.text, 'lxml') # 第二个参数是解析器,不知道为什么,此处不能使用'html.parser'# 为直观一点,多写了点 findindexs = soup.find("div", id="globalWrapper") \.find("div", id="column-content") \.find("div", id="content") \.find("div", id="bodyContent") \.find("div", style="margin:10px 5px;border:1px solid #B2DE90;background-color:#E3F0D8;padding:5px") \.find("div", style="padding:0 5px;") \.find_all('a')# 爬下所需的链接res = []for index in indexs:if len(str(index.get('title'))) > 0:res.append({'title': index.get('title').split('Category:')[1], 'href': index.get('href')})return res
次级分类页面
此时我们进入了第二级页面,以 “金融理论” 为例:
地址:https://wiki.mbalib.com/wiki/Category:%E9%87%91%E8%9E%8D%E7%90%86%E8%AE%BA
在这个页面里,有两个问题:1. 区分“子类”与“条目”;2. 如何找到下一页(如下图),直到没有下一页。
网页格式:
首先来区分“子类”和“条目”:
首先需要定位两框的位置,通过观察,二者均位于 <div id="bodyContent">
中
令人难受的是:“子类”所在的标签竟然与上一级是平级的。
由于以上原因,我们不妨换个思路,先收集所有能够跳转的“条目”和“子类”。
由此,转向第二个问题:如何找到下一页,直到最后。
这里有一个问题:
爬下来的转向下一页的链接:
原网页中转向下一页的链接:
对比可见,爬下来的链接中多了一个&
字节,该字节的含义是’&’, 我们可以用 repalce 转化为实体字符。处理该问题的代码为:
def deal_EscapeCharacter(self, s):return s.replace('&', '&').replace("<", '>').replace(">", '>').replace(""", '"').replace("'", "'")
下面来说如何分开“条目”与“子类”的方案:将分类页面下 bodyContent
下的所有可以链接的条目都爬一遍,检查 url, 若存在字符串’Category’, 则依旧为索引界面;否则即为内容界面。
talk is cheap, show me the code:
def get_classify_html(self, url):if url in self.hadGone:print('Had Gone : ', url)returnr = requests.get(url, headers=self.headers)soup = BeautifulSoup(r.text, 'lxml')# 依旧为了直观indexs = soup.find("div", id="globalWrapper") \.find("div", id="column-content") \.find("div", id="content") \.find("div", id="bodyContent") \.find_all("a")for index in indexs:if index.get('href'):href = self.deal_EscapeCharacter(index.get('href'))self.hadGone.append(href)if 'Category' in (str(index.get('title'))):get_classify_html(self, href)elif index.get('title') and index.get('href') != '#':print(index)return
网页内容解析
接下来解析百科知识页面的内容:
例如:https://wiki.mbalib.com/wiki/%E8%B5%84%E6%9C%AC%E8%B5%84%E4%BA%A7%E5%AE%9A%E4%BB%B7%E6%A8%A1%E5%9E%8B
首先,用以下这一部分的名词作为专业名词术语,存储在 name 中。
之后是专业内容,在该网页中,依照<div class="headline-2">
可以划分为:CAPM模型的提出、资本资产定价模型公式、资本资产定价模型的假设、资本资产定价模型的优缺点、Beta系数等部分。
爬取以上内容时可以将内容分为两大类:1. 图片,即img
,保存其 url;2. 非图片,即<p>
的部分,可以再结合具体内容,分为纯文本、公式、链接、分级等多个类别。例如下图为一个文本公式的样式。
def parse_html(self, url):if url in self.hadGone:print('Had Gone : ', url)returnprint('now :', url)self.hadGone.append(url)r = requests.get(url, headers=self.headers)soup = BeautifulSoup(r.text, 'lxml')# 依旧为了直观indexs = soup.find("div", id="globalWrapper") \.find("div", id="column-content") \.find("div", id="content") \name = indexs.find('h1', class_='firstHeading').stringprint('name:', name) # 大标题,即专业名词indexs = indexs.find("div", id='bodyContent')AllAbout = [] # 一个小标题下所有段落所有可以链接到的的名词AllContent = []SubContent = []SubAbout = []for child in indexs.children:if child.name == 'table': # 省略索引部分continueelif child.name == 'div': # 此处找的是小标题if len(SubContent) > 0:AllContent.append(SubContent)if len(SubAbout) > 0:AllAbout.append(SubAbout)SubContent = []SubAbout = []childChild = child.find('h2')if childChild:SubContent.append(childChild.text.strip())SubAbout.append(childChild.text.strip())elif child.name == 'p': # 小标题下的内容(文本部分)if len(SubContent) > 1:SubContent[-1] += child.textelse:SubContent.append(child.text.strip())# 向 SubAbout 中添加小标题下的链接childChild = child.find_all('a')for index in childChild:SubAbout.append(index.text.strip())# 向 SubContent 中添加小标题下的图片childChild = child.find('img')if childChild:SubContent[-1] += '<img src="' + self.wikiURL + str(childChild['src']) + '">' # 图片解析成 html 支持的格式elif child.name == 'dl': # 'dl' 为小标题内部再分级childChild = child.find('dt')SubContent.append(childChild.text)elif child.name == 'ul': # 'ul' 为'相关条目' 下内容的存储方式childChild = child.find_all('li')for index in childChild:SubAbout.append(index.text.strip())SubContent.append(index.text.strip())
爬虫实战:爬掉 MBA 智库中的百科相关推荐
- 【项目总结】近期爬虫详解(MBA智库百科词条爬虫同花顺财经数据爬虫)
确实鸽了好一阵子了.上学期初心血来潮想要写写博客,写完第一篇博客我才发现写一篇充实的博客是多么费时费力,但是我还是坚持每周一篇博客地写了两个多月,毕竟期初事情也不是很多.直到期中过后我才发现每周余出一 ...
- node 爬虫 实战 - 爬取拉勾网职位数据
node 爬虫 实战 - 爬取拉勾网职位数据,主要想把数据用于大数据学习,到时候大数据分析可以自己分析一下职位的情况,和比较一些我现在的职位在深圳乃至全国的开发人员水平. 涉及到的技术栈:node.j ...
- Python爬虫实战爬取租房网站2w+数据-链家上海区域信息(超详细)
Python爬虫实战爬取租房网站-链家上海区域信息(过程超详细) 内容可能有点啰嗦 大佬们请见谅 后面会贴代码 带火们有需求的话就用吧 正好这几天做的实验报告就直接拿过来了,我想后面应该会有人用的到吧 ...
- python爬虫实战---爬取大众点评评论
python爬虫实战-爬取大众点评评论(加密字体) 1.首先打开一个店铺找到评论 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多 ...
- python爬虫实战-爬取微信公众号所有历史文章 - (00) 概述
http://efonfighting.imwork.net 欢迎关注微信公众号"一番码客"获取免费下载服务与源码,并及时接收最新文章推送. 最近几年随着人工智能和大数据的兴起,p ...
- Scrapy 爬虫实战-爬取字幕库
Scrapy 爬虫实战-爬取字幕库 1.首先,创建Scrapy框架 创建工程 scrapy startproject zimuku创建爬虫程序 cd zimuku scrapy genspider z ...
- python爬虫练习--爬取站长素材中免费简历模板
python爬虫练习--爬取站长素材中免费简历模板 一.需求 二.代码 1. 引入库 2. main() 3. saveData(div_list) 4. 收尾 结语 一.需求 此代码是为完成波波老师 ...
- python爬虫实战-爬取视频网站下载视频至本地(selenium)
#python爬虫实战-爬取视频网站下载视频至本地(selenium) import requests from lxml import etree import json from selenium ...
- 九 web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解...
封装模块 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib from urllib import request import j ...
最新文章
- IEEE论文:城市大脑,基于互联网大脑模型的智慧城市建设
- 正则表达式笔记(谷歌分析自定义报告)
- 解决Eclipse安装Genymotion插件后抛异常的Bug
- 想找一个写Wiki的工具
- (NO.00003)iOS游戏简单的机器人投射游戏成形记(一)
- php和c语言那个竞争大,【后端开发】php和c语言哪个难
- win2008服务器系统功能,详解Win2008初始配置任务功能的应用
- faststart可以卸载吗_你的手机你做主!免 ROOT 卸载安卓手机预装APP
- 怎样用计算机算出圆周率,古代没有计算机的时代 祖冲之是如何算出圆周率的...
- vsftpd配置系统用户为登陆用户
- mac上面比较好用的软件
- 2021牛客暑期多校训练营#10:F-Train Wreck
- JavaScript 是怎么运行起来的?
- 奥维查看行政边界_全国乡镇行政区划数据乡镇边界数据查询获取方式
- 【BUG记录】Idea spring boot项目中target中没有同步更新最新目录文件及资源
- haproxy log日志简单记录
- authorization配置
- GStreamer基础教程10——GStreamer工具
- Win10远程桌面连接不上Win7的桌面的一次奇葩经历
- SSR(服务端渲染)、CSR(客户端渲染)和预渲染