一、问题描述

之前爬虫过程主要存在两个个问题:
(1)爬取到网页源码之后,没有解析,直接利用正则表达式抓取信息,这样做起来比较费劲,容易造成信息抓取不全面,同时,所有页面链接都是根据链接规律自建的,没有做到自动爬取。
(2)代码未做模块化处理,检查错误比较难。
在改善了上述两个问题之后,重新爬取了百度百科中疾病信息库,并保存在.xlsx文件中

二、网页分析及爬虫结构

1、网页分析

爬虫入口链接:root_url=“http://baike.baidu.com/fenlei/%E7%96%BE%E7%97%85”
爬虫入口页面:

红圈对应源码位置为该疾病链接,蓝圈对应位置为每个分页链接
因此本次爬虫的过程为:依次爬取每页所有疾病链接,进而根据疾病链接爬取疾病信息

2、爬虫结构

(1)url 集合
urls_0=set():主页链接集合(未爬取)
urls_1=set():疾病页面链接集合(未爬取)
new_url_0:主页链接(即将爬取)
new_url_1:疾病链接(即将爬取)
old_urls=set():所有已爬取链接集合(防止重复爬取)

(2)模块
main: 主程序(调度,保存数据)
url_manager :url管理器(url保存,提取,查空)
html_downloader :html下载器(下载HTML)
html_parser :html解析器(提取主页内疾病链接和疾病页面内所需信息)

(3)爬取过程

三、具体模块代码

为方便查看,将主模块放在最后

1、url_manager :url管理器(url保存,提取,查空)

class UrlManager(object):def __init__(self):self.new_urls_0=set()#主页链接集合(未爬取)self.new_urls_1=set()#疾病链接集合(未爬取)self.old_urls=set()#已爬取链接集合#单一url添加到url_set中  def add_new_url(self,url,url_set):if url is None:return if url not in url_set and url not in self.old_urls:url_set.add(url)#多个url添加到url_set中     def add_new_urls(self,urls,url_set):if urls is None or len(urls)==0:returnfor url in urls:self.add_new_url(url,url_set)#从url_set中获取一个url ,同时将该url添加到old_url集合中      def get_new_url(self,url_set):new_url=url_set.pop()self.old_urls.add(new_url)return new_url#判断url_set中是否还有未爬取的url  def has_new_url(self,url_set):return len(url_set)!=0

2、html_downloader :html下载器(下载HTML)

import urllib.request
import urllibclass HtmlDownloader(object):def __init__(self):pass#下载htmldef download(self,url):if url is None:return Noneprint ("html downloading")i=1 #设置开关,报错时继续下载该HTML,配合urlop.close()主要为了解决10054(拒绝访问)报错#如果报错信息不是10054,Ctrl+C终止循环,改错后继续while i==1:i=0try:urlop=urllib.request.urlopen(url,timeout=100)data=urlop.read().decode('utf-8')urlop.close()except Exception as e:print(e)i=1return data

3、html_parser :html解析器(提取主页内疾病链接和疾病页面内所需信息)

from bs4 import BeautifulSoup
import re
class HtmlParser(object):#返回页面中的所有链接def parse_url(self,url_r,html_cont):soup=BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')new_urls_0=self._get_new_urls_0(url_r,soup)new_urls_1=self._get_new_urls_1(soup)return new_urls_0,new_urls_1#返回页面中爬取的数据信息def parse_data(self,html_cont):soup=BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')new_data=self._get_new_data(soup)return new_data#解析得到html中的所有疾病链接 def _get_new_urls_1(self,soup):new_urls_1=set()#获取本页疾病链接#例:<a href="/view/124636.htm" class="pic-content nslog:7450" title="骨髓瘤" target="_blank">links_1=soup.find_all('a',href=re.compile(r"/view/\d+\.htm"))for link in links_1:new_url=link['href']new_full_url='http://baike.baidu.com'+new_urlnew_urls_1.add(new_full_url)return new_urls_1#解析得到html中的页面链接def _get_new_urls_0(self,url_r,soup):new_urls_0=set()#获取更多页面链接#例:<a href="疾病?limit=30&index=2&offset=30#gotoList" class="nslog:7453">links_0=soup.find_all('a',href=re.compile(r"\?limit=\d+&index=\d+&offset=\d+\#gotoList"))for link in links_0:new_url=link['href']new_full_url=url_r+new_url[2::]#构造完整链接new_urls_0.add(new_full_url)return new_urls_0#解析得到疾病页面中的标题(title)、简介(summary)    、基本信息def _get_new_data(self,soup):res_data={}#title 示例#<dd class="lemmaWgt-lemmaTitle-title">#<h1 >骨关节炎</h1>title_node=soup.find('dd', class_="lemmaWgt-lemmaTitle-title").find("h1")res_data['疾病名']=str(title_node.string)#summer示例#<div class="lemma-summary" label-module="lemmaSummary">#<div class="para" label-module="para">骨<a target=_blank。。。关节畸形等。</div>summary_node=soup.find_all('div',class_="lemma-summary")soup_summary=BeautifulSoup(str(summary_node), 'lxml')#简介res_data['简介']=str(soup_summary.div.text)#<div class="dl-baseinfo">#base_inf=soup.find_all('div',attrs={"class":"dl-baseinfo"})[0].find_all('dd')for i in soup.find_all('div',attrs={"class":"dl-baseinfo"}):item=i.find_all('dt')inf=i.find_all('dd')for j,x in enumerate(item):try:res_data[x.string]=','.join(re.findall('\S+',inf[j].string))   except Exception as e:print(e)res_data[x.string]=Nonereturn res_data

4、main: 主程序(调度,保存数据)
为方便对照,将爬虫结构图再次放置

#上述模块保存后调用
import url_manager,html_downloader,html_parser
import openpyxl
class Main(object):def __init__(self):self.urls=url_manager.UrlManager()#url管理器self.downloader=html_downloader.HtmlDownloader()#html下载器self.parser=html_parser.HtmlParser()#html解析器self.sheet=sheetdef craw(self,root_url):urls_0=self.urls.new_urls_0#新页面url集合urls_1=self.urls.new_urls_1#新疾病url集合self.urls.add_new_url(root_url,urls_0)#将爬虫入口添加到新页面url集合count=0#页面数目row=1#数据总条目while self.urls.has_new_url(urls_0):#爬完所有页面时停止i=0#同一页面下,所爬取疾病数目count+=1new_url_0=self.urls.get_new_url(urls_0)#从页面url集合获取一个url,并将其放入old_urls中print ("页面 %d: %s"%(count,new_url_0))html_cont=self.downloader.download(new_url_0)#下载htmlnew_urls_0,new_urls_1=self.parser.parse_url(root_url,html_cont)#获取页面html中的新页面链接和疾病链接self.urls.add_new_urls(new_urls_0,urls_0)#保存新页面链接self.urls.add_new_urls(new_urls_1,urls_1)#保存疾病链接#print(urls_0)while self.urls.has_new_url(urls_1):#爬完本页所有疾病时停止i+=1new_url_1=self.urls.get_new_url(urls_1)#获取一个疾病链接,并添加到old_urls中print('页面 %d 疾病 %d: %s'%(count,i,new_url_1))html_cont=self.downloader.download(new_url_1)#下载疾病页面htmlnew_data=self.parser.parse_data(html_cont) #提取所需信息row+=1#每爬取一个疾病信息,数据总数加一print(row)#输入已爬取总数#print(new_data['疾病名'])#print(new_data)#return new_data#写入表格for data in new_data:if data in items:sheet.cell(row,items.index(data)+1,new_data[data])if __name__=="__main__":#表头内容items= ['疾病名', '英文名称', '就诊科室', '常见发病', '常见病因', '常见症状', '简介']#爬虫入口root_url="http://baike.baidu.com/fenlei/%E7%96%BE%E7%97%85"#载入表格workbook=openpyxl.load_workbook(r'C:\Users\Administrator\Desktop\jibing2.xlsx')#获取sheetsheet=workbook.worksheets[0]#添加表头for i,x in enumerate(items):sheet.cell(1,i+1,x)obj_spider=Main()#调用爬虫调度程序obj_spider.craw(root_url)#保存数据workbook.save(r'C:\Users\Administrator\Desktop\jibing2.xlsx')

四、报错及结果

1、报错信息

(1)
TypeError: 'str' object is not callable
原因是定义了一个str变量,但是该变量名是系统本身的函数或者自定义函数,发生冲突,更改该变量名即可
(2)

openpyxl
sheet.cell(0,0,x)
ValueError: Row or column values must be at least 1

报错原因:
openpyxl表格位置计数从1开始,并非从0开始
(3)

save_workbook(self, filename)
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\Administrator\\Desktop\\jibing2.xlsx'

错误原因:
当前表格处于打开状态,关闭表格后重试
2、运行过程

python3爬虫---百度百科(疾病信息)相关推荐

  1. AI Studio学习篇3_《乘风破浪的姐姐》百度百科嘉宾信息爬取与数据分析

    目录 爬取 分析 一.爬取 1.先拿到各个嘉宾的姓名和详情页链接 查看页面结构 可以根据table的标题来筛选要找的table,就是"按姓氏首字母排序" 将这些嘉宾的信息存入到js ...

  2. python爬取百度地图_python 爬虫百度地图的信息界面的实现方法

    python 爬虫百度地图的信息界面的实现方法 发布时间:2020-09-23 00:02:08 来源:脚本之家 阅读:78 作者:猫苘 在爬虫百度地图的期间,就为它做了一个界面,运用的是PyQt5. ...

  3. 我的第一个Python3 网络爬虫 百度百科爬虫

    最近学习Python 廖雪峰老师的Python 3教程 想要用项目练练手.Python网络爬虫看起来是不错的练手项目,于是着手学习爬虫的制作. 一开始并没有什么头绪,直到看到了慕课网的Python爬虫 ...

  4. python爬虫百度百科-如何入门 Python 爬虫?

    目前网上有关网页爬虫的指导有很多,但是套路却是千篇一律,基本都是围绕以下内容进行展开,CSS/html等网页知识 requests或urllib BeautifulSoup或正则表达式 Seleniu ...

  5. python爬虫百度百科-python爬虫(一)_爬虫原理和数据抓取

    本篇将开始介绍Python原理,更多内容请参考:Python学习指南 为什么要做爬虫 著名的革命家.思想家.政治家.战略家.社会改革的主要领导人物马云曾经在2015年提到由IT转到DT,何谓DT,DT ...

  6. python爬虫︱百度百科的requests请求、百度URL格式、网页保存、爬虫模块

    1 . 百科网页请求 1.1 网站解析requests与urllib.request对比: py3中主要用requests以及urllib.request两款库用来做网页内容的解析,两者的使用较多以r ...

  7. python爬虫百度百科-python每日一题:网络爬虫百度百科

    # !控制主机程序 '''主机发送爬虫网址,从机进行爬取信息,并返回给主机''' #本次优化主要是:由于发送url与爬取url速度差异较大,造成发送url的队列中存在数据较多,占用内存. # 新方案是 ...

  8. Python3爬虫(sqlite3存储信息)--AGE动漫网站排行榜

             目录 目标 1.爬虫代码 1.1运行结果 1.2爬虫难点 1.2.1编写正则表达式: 1.3爬虫中的不足 1.3.1抓取的动漫播放链接不够完整 2.GUI展现爬虫内容 2.1思路 2 ...

  9. 【爬虫实战】10应用Python网络爬虫——定向爬取百度百科文字

    python百度百科爬虫 网页源代码分析 编程实现 小结 网页源代码分析 首先找一下需要爬取的正文: 对应的源代码有两个地方: 上图往后翻会发现省略号,所以下面这张图才是我们需要爬取的部分: 编程实现 ...

最新文章

  1. EXCEL 找出重复的记录 COUNTIF
  2. python设置环境路径_window10配置python虚拟环境的路径
  3. 一道微软面试题的运算过程解析
  4. Linux库概念及相关编程(动态库、静态库、环境变量)
  5. 写出漂亮代码的七种方法
  6. 网络协议:ARP协议
  7. C/C++多种方法获取文件大小(转)
  8. /common/nlp/data/dictionary/CoreNatureDictionary.mini.txt加载失败
  9. Win 10 下载与安装 Oracle 12c 详细图解 与 Oracle 12c 卸载
  10. c语言电子时钟课程设计报告,模拟电子时钟c语言课程设计设计报告.doc
  11. 最近写的一个书店项目
  12. 震旦复印机扫描到服务器文件夹,办公室复印机怎么扫描文件(图示复印机扫描功能应用)...
  13. ubuntu永久修改mac地址
  14. VS2012,发布时出现“不支持此接口”错误的解决办法……
  15. 谢烟客---------Linux之深入理解anaconda使用
  16. 今天在网上找QQ头像,找到两个字,太强了,一个我老婆的名字,另一个.....用了肯定有人打我脸
  17. iphone11各机型对比_三款机型运行速度对比,iPhone11Pro表现如何?
  18. java简单程序彩票系统!
  19. html/css--flex布局
  20. 奥克斯空调红外遥控信号编码协议的分析,STC51单片机读红外程序

热门文章

  1. N个技巧,编写更高效 Dockerfile|云效工程师指北
  2. 转自【帮助中心】 C币的相关规则
  3. maven 报错 Failed to create assembly: archive cannot be empty
  4. MarchingCubes算法
  5. ImageNet、CIFAR、MNIST、IMDB、AudioSet等10个数据集中的标签错误分析
  6. nessus10.0.2更新
  7. opendir/readdir/closedir函数
  8. idea module ‘xxx‘ does exits 删除原来子项目重新建立报错
  9. Bugku Misc 账号被盗了
  10. [学习计划]QSC Q-SYS Level 1 音频处理器