目标

首先说下目标: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">

令人难受的是:“子类”所在的标签竟然与上一级是平级的。

由于以上原因,我们不妨换个思路,先收集所有能够跳转的“条目”和“子类”。

由此,转向第二个问题:如何找到下一页,直到最后。

这里有一个问题:
爬下来的转向下一页的链接:

原网页中转向下一页的链接:

对比可见,爬下来的链接中多了一个&amp;字节,该字节的含义是’&’, 我们可以用 repalce 转化为实体字符。处理该问题的代码为:

def deal_EscapeCharacter(self, s):return s.replace('&amp;', '&').replace("&lt;", '>').replace("&gt;", '>').replace("&quot;", '"').replace("&apos;", "'")

下面来说如何分开“条目”与“子类”的方案:将分类页面下 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 智库中的百科相关推荐

  1. 【项目总结】近期爬虫详解(MBA智库百科词条爬虫同花顺财经数据爬虫)

    确实鸽了好一阵子了.上学期初心血来潮想要写写博客,写完第一篇博客我才发现写一篇充实的博客是多么费时费力,但是我还是坚持每周一篇博客地写了两个多月,毕竟期初事情也不是很多.直到期中过后我才发现每周余出一 ...

  2. node 爬虫 实战 - 爬取拉勾网职位数据

    node 爬虫 实战 - 爬取拉勾网职位数据,主要想把数据用于大数据学习,到时候大数据分析可以自己分析一下职位的情况,和比较一些我现在的职位在深圳乃至全国的开发人员水平. 涉及到的技术栈:node.j ...

  3. Python爬虫实战爬取租房网站2w+数据-链家上海区域信息(超详细)

    Python爬虫实战爬取租房网站-链家上海区域信息(过程超详细) 内容可能有点啰嗦 大佬们请见谅 后面会贴代码 带火们有需求的话就用吧 正好这几天做的实验报告就直接拿过来了,我想后面应该会有人用的到吧 ...

  4. python爬虫实战---爬取大众点评评论

    python爬虫实战-爬取大众点评评论(加密字体) 1.首先打开一个店铺找到评论 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多 ...

  5. python爬虫实战-爬取微信公众号所有历史文章 - (00) 概述

    http://efonfighting.imwork.net 欢迎关注微信公众号"一番码客"获取免费下载服务与源码,并及时接收最新文章推送. 最近几年随着人工智能和大数据的兴起,p ...

  6. Scrapy 爬虫实战-爬取字幕库

    Scrapy 爬虫实战-爬取字幕库 1.首先,创建Scrapy框架 创建工程 scrapy startproject zimuku创建爬虫程序 cd zimuku scrapy genspider z ...

  7. python爬虫练习--爬取站长素材中免费简历模板

    python爬虫练习--爬取站长素材中免费简历模板 一.需求 二.代码 1. 引入库 2. main() 3. saveData(div_list) 4. 收尾 结语 一.需求 此代码是为完成波波老师 ...

  8. python爬虫实战-爬取视频网站下载视频至本地(selenium)

    #python爬虫实战-爬取视频网站下载视频至本地(selenium) import requests from lxml import etree import json from selenium ...

  9. 九 web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解...

    封装模块 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib from urllib import request import j ...

最新文章

  1. IEEE论文:城市大脑,基于互联网大脑模型的智慧城市建设
  2. 正则表达式笔记(谷歌分析自定义报告)
  3. 解决Eclipse安装Genymotion插件后抛异常的Bug
  4. 想找一个写Wiki的工具
  5. (NO.00003)iOS游戏简单的机器人投射游戏成形记(一)
  6. php和c语言那个竞争大,【后端开发】php和c语言哪个难
  7. win2008服务器系统功能,详解Win2008初始配置任务功能的应用
  8. faststart可以卸载吗_你的手机你做主!免 ROOT 卸载安卓手机预装APP
  9. 怎样用计算机算出圆周率,古代没有计算机的时代 祖冲之是如何算出圆周率的...
  10. vsftpd配置系统用户为登陆用户
  11. mac上面比较好用的软件
  12. 2021牛客暑期多校训练营#10:F-Train Wreck
  13. JavaScript 是怎么运行起来的?
  14. 奥维查看行政边界_全国乡镇行政区划数据乡镇边界数据查询获取方式
  15. 【BUG记录】Idea spring boot项目中target中没有同步更新最新目录文件及资源
  16. haproxy log日志简单记录
  17. authorization配置
  18. GStreamer基础教程10——GStreamer工具
  19. Win10远程桌面连接不上Win7的桌面的一次奇葩经历
  20. SSR(服务端渲染)、CSR(客户端渲染)和预渲染

热门文章

  1. 雨林木风倾心之作——Windows一键还原试用评点
  2. 计算机硬件评分,geekbench4最新版本
  3. linux把test目录打包,linux的基本操作(文件压缩与打包)
  4. 马桶MT、聊天宝、多闪齐遭封杀,看云通讯产业如何变局?
  5. IClone地形编辑器结合T4M插件在Unity3D使用
  6. Trucksim软件安装及找不到license问题的解决办法
  7. 电脑办公记事app软件哪个好用?
  8. 怎么理解内存中的Buffer和Cache
  9. MobaXterm 软件的安装与使用
  10. mysql优化步骤及方法