Python爬虫实现爬取百度百科词条功能实例


Posted in Python onApril 05, 2019

本文实例讲述了Python爬虫实现爬取百度百科词条功能。分享给大家供大家参考,具体如下:

爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索。常见的爬虫框架有Scrapy等。

自定义爬虫程序一般包含:URL管理器、网页下载器、网页解析器、输出处理器。

以下我写了一个爬取百度百科词条的实例。

爬虫主程序入口

from crawler_test.html_downloader import UrlDownLoader
from crawler_test.html_outer import HtmlOuter
from crawler_test.html_parser import HtmlParser
from crawler_test.url_manager import UrlManager
# 爬虫主程序入口
class MainCrawler():
  def __init__(self):
    # 初始值,实例化四大处理器:url管理器,下载器,解析器,输出器
    self.urls = UrlManager()
    self.downloader = UrlDownLoader()
    self.parser = HtmlParser()
    self.outer = HtmlOuter()
  # 开始爬虫方法
  def start_craw(self, main_url):
    print('爬虫开始...')
    count = 1
    self.urls.add_new_url(main_url)
    while self.urls.has_new_url():
      try:
        new_url = self.urls.get_new_url()
        print('爬虫%d,%s' % (count, new_url))
        html_cont = self.downloader.down_load(new_url)
        new_urls, new_data = self.parser.parse(new_url, html_cont)
        # 将解析出的url放入url管理器,解析出的数据放入输出器中
        self.urls.add_new_urls(new_urls)
        self.outer.conllect_data(new_data)
        if count >= 10:# 控制爬取的数量
          break
        count += 1
      except:
        print('爬虫失败一条')
    self.outer.output()
    print('爬虫结束。')
if __name__ == '__main__':
  main_url = 'https://baike.baidu.com/item/Python/407313'
  mc = MainCrawler()
  mc.start_craw(main_url)

URL管理器

# URL管理器
class UrlManager():
  def __init__(self):
    self.new_urls = set() # 待爬取
    self.old_urls = set() # 已爬取
  # 添加一个新的url
  def add_new_url(self, url):
    if url is None:
      return
    elif url not in self.new_urls and url not in self.old_urls:
      self.new_urls.add(url)
  # 批量添加url
  def add_new_urls(self, urls):
    if urls is None or len(urls) == 0:
      return
    else:
      for url in urls:
        self.add_new_url(url)
  # 判断是否有url
  def has_new_url(self):
    return len(self.new_urls) != 0
  # 从待爬取的集合中获取一个url
  def get_new_url(self):
    new_url = self.new_urls.pop()
    self.old_urls.add(new_url)
    return new_url

网页下载器

from urllib import request
# 网页下载器
class UrlDownLoader():
  def down_load(self, url):
    if url is None:
      return None
    else:
      rt = request.Request(url=url, method='GET')   # 发GET请求
      with request.urlopen(rt) as rp:         # 打开网页
        if rp.status != 200:
          return None
        else:
          return rp.read()            # 读取网页内容

网页解析器

import re
from urllib import parse
from bs4 import BeautifulSoup
# 网页解析器,使用BeautifulSoup
class HtmlParser():
  # 每个词条中,可以有多个超链接
  # main_url指url公共部分,如“https://baike.baidu.com/”
  def _get_new_url(self, main_url, soup):
    # baike.baidu.com/
    # <a target="_blank" href="/item/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80" rel="external nofollow" >计算机程序设计语言</a>
    new_urls = set()
    # 解析出main_url之后的url部分
    child_urls = soup.find_all('a', href=re.compile(r'/item/(\%\w{2})+'))
    for child_url in child_urls:
      new_url = child_url['href']
      # 再拼接成完整的url
      full_url = parse.urljoin(main_url, new_url)
      new_urls.add(full_url)
    return new_urls
  # 每个词条中,只有一个描述内容,解析出数据(词条,内容)
  def _get_new_data(self, main_url, soup):
    new_datas = {}
    new_datas['url'] = main_url
    # <dd class="lemmaWgt-lemmaTitle-title"><h1>计算机程序设计语言</h1>...
    new_datas['title'] = soup.find('dd', class_='lemmaWgt-lemmaTitle-title').find('h1').get_text()
    # class="lemma-summary" label-module="lemmaSummary"...
    new_datas['content'] = soup.find('div', attrs={'label-module': 'lemmaSummary'},
                     class_='lemma-summary').get_text()
    return new_datas
  # 解析出url和数据(词条,内容)
  def parse(self, main_url, html_cont):
    if main_url is None or html_cont is None:
      return
    soup = BeautifulSoup(html_cont, 'lxml', from_encoding='utf-8')
    new_url = self._get_new_url(main_url, soup)
    new_data = self._get_new_data(main_url, soup)
    return new_url, new_data

输出处理器

# 输出器
class HtmlOuter():
  def __init__(self):
    self.datas = []
  # 先收集数据
  def conllect_data(self, data):
    if data is None:
      return
    self.datas.append(data)
    return self.datas
  # 输出为HTML
  def output(self, file='output_html.html'):
    with open(file, 'w', encoding='utf-8') as fh:
      fh.write('<html>')
      fh.write('<head>')
      fh.write('<meta charset="utf-8"></meta>')
      fh.write('<title>爬虫数据结果</title>')
      fh.write('</head>')
      fh.write('<body>')
      fh.write(
        '<table style="border-collapse:collapse; border:1px solid gray; width:80%; word-break:break-all; margin:20px auto;">')
      fh.write('<tr>')
      fh.write('<th style="border:1px solid black; width:35%;">URL</th>')
      fh.write('<th style="border:1px solid black; width:15%;">词条</th>')
      fh.write('<th style="border:1px solid black; width:50%;">内容</th>')
      fh.write('</tr>')
      for data in self.datas:
        fh.write('<tr>')
        fh.write('<td style="border:1px solid black">{0}</td>'.format(data['url']))
        fh.write('<td style="border:1px solid black">{0}</td>'.format(data['title']))
        fh.write('<td style="border:1px solid black">{0}</td>'.format(data['content']))
        fh.write('</tr>')
      fh.write('</table>')
      fh.write('</body>')
      fh.write('</html>')

效果(部分):

Python爬虫实现爬取百度百科词条功能实例

更多关于Python相关内容可查看本站专题:《Python Socket编程技巧总结》、《Python正则表达式用法总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python基础教程之自定义函数介绍
Aug 29 Python
Python文件及目录操作实例详解
Jun 04 Python
Python 中的with关键字使用详解
Sep 11 Python
pip matplotlib报错equired packages can not be built解决
Jan 06 Python
理想高通滤波实现Python opencv示例
Jan 30 Python
Django密码存储策略分析
Jan 09 Python
对python中 math模块下 atan 和 atan2的区别详解
Jan 17 Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
Mar 25 Python
python爬取股票最新数据并用excel绘制树状图的示例
Mar 01 Python
一些让Python代码简洁的实用技巧总结
Aug 23 Python
Python+Matplotlib+LaTeX玩转数学公式
Feb 24 Python
Python 文字识别
May 11 Python
Python3.5多进程原理与用法实例分析
Apr 05 #Python
Python选择网卡发包及接收数据包
Apr 04 #Python
详解Python的数据库操作(pymysql)
Apr 04 #Python
python dlib人脸识别代码实例
Apr 04 #Python
python图像处理入门(一)
Apr 04 #Python
python爬虫简单的添加代理进行访问的实现代码
Apr 04 #Python
Django项目中添加ldap登陆认证功能的实现
Apr 04 #Python
You might like
利用PHP获取汉字首字母并且分组排序详解
2017/10/22 PHP
PHP设计模式之组合模式定义与应用示例
2020/02/01 PHP
jQuery each()小议
2010/03/18 Javascript
基于jquery的图片轮播 tab切换组件
2012/07/19 Javascript
JS跨域总结
2012/08/30 Javascript
JQuery调用绑定click事件的3种写法
2015/03/28 Javascript
JavaScript中对DOM节点的访问、创建、修改、删除
2015/11/16 Javascript
JavaScript实现点击按钮直接打印
2016/01/06 Javascript
基于JQuery实现分隔条的功能
2016/06/17 Javascript
JavaScript禁止用户多次提交的两种方法
2016/07/24 Javascript
JS 设置Cookie 有效期 检测cookie
2017/06/15 Javascript
微信小程序实现根据字母选择城市功能
2017/08/16 Javascript
jquery 实现拖动文件上传加载进度条功能
2018/03/18 jQuery
vue.js实现的幻灯片功能示例
2019/01/18 Javascript
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
2019/03/02 NodeJs
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
layui2.0使用table+laypage实现真分页
2019/07/27 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
python合并文本文件示例
2014/02/07 Python
Python使用functools模块中的partial函数生成偏函数
2016/07/02 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
Python可迭代对象操作示例
2019/05/07 Python
一篇文章搞定Python操作文件与目录
2019/08/13 Python
python图像处理模块Pillow的学习详解
2019/10/09 Python
迪卡侬英国官网:Decathlon英国
2017/04/08 全球购物
Champs Sports加拿大:北美最大的以商场为基础的专业运动鞋和服装零售商之一
2018/05/01 全球购物
什么是.net的Remoting技术
2016/07/08 面试题
银行工作检查书范文
2014/01/31 职场文书
行政副总岗位职责
2014/02/23 职场文书
行政部岗位职责范本
2014/03/13 职场文书
治安消防安全责任书
2014/07/23 职场文书
2014年乡镇党建工作总结
2014/11/11 职场文书
2014年销售工作总结
2014/12/01 职场文书
2015年感恩节演讲稿(优选篇)
2015/03/20 职场文书
负责培养人意见
2015/06/05 职场文书
导游词之岳阳楼
2019/09/25 职场文书