Python网络爬虫案例:维基百科

1.项目描述

本案例的目标是爬取维基百科上的词条连接。爬虫深度设置为两层。

网络蜘蛛:是通过网页的链接地址寻找网页的,从网站某一个页面(通常是首页)开始读取网页的内容,找到在网页中其他链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。

如何把整个网站的所有网页都爬取一遍呢?涉及到两个基本算法:基于深度优先的遍历和基于广度优先的遍历。

2.网站分析

网页首页为:https://en.wikipedia.org/wiki/Wikipedia

首先,分析词条链接的特点;

然后,得到该页面的所有链接:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File  : GetLink.py
@Author: Xinzhe.Pang
@Date  : 2019/7/18 20:44
@Desc  :
"""
import requests
from bs4 import BeautifulSoupurl = "https://en.wikipedia.org/wiki/Wikipedia"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}r = requests.get(url, headers=headers)
html = r.text
bsObj = BeautifulSoup(html)for link in bsObj.find_all("a"):if 'href' in link.attrs:print(link.attrs['href'])

通过分析,可以发现所有词条的链接有两个特点:

(1)URL链接是以/wiki/开头的相对路径;

(2)URL链接不包括冒号、#、=、<、>。

这里,直接用正则表达式从网页HTML代码中提取需要的词条链接,正则表达式为<a href="/wiki/([^:#=<>]*?)".*?</a>。

3.深度优先的递归爬虫

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File  : DeepFirst.py
@Author: Xinzhe.Pang
@Date  : 2019/7/18 21:13
@Desc  :
"""
import requests
import reexist_url = []  # 存放已爬取的网页
g_writecount = 0def scrappy(url, depth=1):global g_writecounttry:headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}url = "https://en.wikipedia.org/wiki/" + urlr = requests.get(url, headers=headers)html = r.textexcept Exception as e:print('Failed downloading and saving', url)print(e)exist_url.append(url)return Noneexist_url.append(url)link_list = re.findall('<a href="/wiki/([^:#=<>]*?)".*?</a>', html)# 去掉已爬链接和重复链接unique_list = list(set(link_list) - set(exist_url))# 把所有链接写出到txt文件for eachone in unique_list:g_writecount += 1output = "No." + str(g_writecount) + "\t Depth:" + str(depth) + "\t" + url + ' -> ' + eachone + '\n'print(output)with open('link_12-3.txt', "a+") as f:f.write(output)# 只获取两层,"Wikipedia"算第一层if depth < 2:# 递归调用自己来访问下一层scrappy(eachone, depth + 1)scrappy("Wikipedia")

每一个新获取的链接都有要先保存到TXT文件中,再使用递归函数调用。

4.广度优先的多线程爬虫

多线程爬虫配合广度优先算法正好。广度优先的遍历算法以层为顺序,将某一层上的所有节点都搜索到了之后才向下一层搜索,可以有大量词条链接放入多线程爬虫的队列中。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File  : BreadthFirst.py
@Author: Xinzhe.Pang
@Date  : 2019/7/18 21:34
@Desc  :
"""
import re
import time
import threading
import requestsg_mutex = threading.Condition()
g_pages = []  # 从中解析所有urll链接
g_queueURL = []  # 等待爬取的url链接列表
g_existURL = []  # 已经爬取过的url链接列表
g_writecount = []  # 找到的链接数class Crawler:def __init__(self, url, threadnum):self.url = urlself.threadnum = threadnumself.threadpool = []# 爬虫的控制大脑,包括爬取网页,更新队列def craw(self):global g_queueURLg_queueURL.append(url)depth = 1while (depth < 3):print('Searching depth ', depth, '...\n')self.downloadAll()self.updateQueueURL()g_pages = []depth += 1# 调用多线程爬虫,在小于线程最大值和没爬完队列之前会增加线程def downloadAll(self):global g_queueURLi = 0while i < len(g_queueURL):j = 0while j < self.threadnum and i + j < len(g_queueURL):threadresult = self.download(g_queueURL[i + j], j)j += 1i += jfor thread in self.threadpool:thread.join(30)threadpool = []g_queueURL = []# 调用多线程爬虫def download(self, url, tid):crawthread = CrawlerThread(url, tid)self.threadpool.append(crawthread)crawthread.start()# 完成一个深度的爬虫之后更新队列def updateQueueURL(self):global g_queueURLglobal g_existURLnewUrlList = []for content in g_pages:newUrlList += self.getUrl(content)g_queueURL = list(set(newUrlList) - set(g_existURL))# 从获取的网页中解析urldef getUrl(self, content):link_list = re.findall('<a href="/wiki/([^:#=<>]*?)".*?</a>', content)unique_list = list(set(link_list))return unique_list# 爬虫线程
class CrawlerThread(threading.Thread):def __init__(self, url, tid):threading.Thread.__init__(self)self.url = urlself.tid = tiddef run(self):global g_mutexglobal g_writecounttry:print(self.tid, "crawl ", self.url)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}r = requests.get("https://en.wikipedia.org/wiki/" + self.url, headers=headers)html = r.textlink_list2 = re.findall('<a href="/wiki/([^:#=<>]*?)".*?</a>', html)unique_list2 = list(set(link_list2))for eachone in unique_list2:g_writecount += 1content2 = "No." + str(g_writecount) + "\t Thread:" + str(self.tid) + "\t" + self.url + ' -> ' + eachone + '\n'with open('title2.txt', "a+") as f:f.write(content2)f.close()except Exception as e:g_mutex.acquire()g_existURL.append(self.url)g_mutex.release()print('Failed downloading and saving', self.url)print(e)return Noneg_mutex.acquire()g_pages.append(html)g_existURL.append(self.url)g_mutex.release()if __name__ == "__main__":url = "Wikipedia"threadnum = 5crawler = Crawler(url, threadnum)crawler.craw()

补充说明:由于网络问题,无法登录https://en.wikipedia.org/wiki/Wikipedia,所以,上述代码仅供学习参考。如果有条件,可以考虑翻墙之后再行实验。

参考资料:《Python网络爬虫从入门到实践》

【Python爬虫】Python网络爬虫案例:维基百科相关推荐

  1. python从零基础到项目实战怎么样-Python 3.x网络爬虫从零基础到项目实战

    ● 案例完整 本书中的所有案例都是通过"理论讲解 + 环境搭建 + 完整代码及分析 + 运行结果"这种完善的结构进行讲解的.此外,复杂的案例配有项目结构图,有难度的案例还分析了底层 ...

  2. python数据采集有哪些技术_如何快速掌握Python数据采集与网络爬虫技术

    一.数据采集与网络爬虫技术简介 网络爬虫是用于数据采集的一门技术,可以帮助我们自动地进行信息的获取与筛选.从技术手段来说,网络爬虫有多种实现方案,如PHP.Java.Python ....那么用pyt ...

  3. python爬虫简单实例-Python 利用Python编写简单网络爬虫实例3

    利用Python编写简单网络爬虫实例3 by:授客 QQ:1033553122 实验环境 python版本:3.3.5(2.7下报错 实验目的 获取目标网站"http://bbs.51tes ...

  4. python简单网络爬虫_【Python】 简单网络爬虫实现

    介绍网络爬虫(英语:网络爬虫),也称为网络蜘蛛(蜘蛛)是一个Web机器人用于自动浏览万维网.其目的通常是为了编译web索引.\u2014\u2014维基百科web爬虫程序可以节省他们访问的页面,以便搜 ...

  5. Python教程:网络爬虫快速入门实战解析

    建议: 请在电脑的陪同下,阅读本文.本文以实战为主,阅读过程如稍有不适,还望多加练习. 网络爬虫简介 网络爬虫,也叫网络蜘蛛(Web Spider).它根据网页地址(URL)爬取网页内容,而网页地址( ...

  6. 【Python笔记】网络爬虫——介绍

    初识网络爬虫 网络爬虫概述 网络爬虫的分类 通用式网络爬虫 聚焦网络爬虫 增量式网络爬虫 深层网络爬虫 网络爬虫的基本原理 随着大数据时代的来临,网络信息量也变得更多.更大.网络爬虫在互联网中的地位将 ...

  7. python为什么叫爬虫-python为什么叫网络爬虫

    爬虫可以抓取网站或应用程序的内容并提取有用的价值,它还可以模拟用户在浏览器或应用程序上的操作,以实现自动化程序.今天小编主要给大家分享python为什么叫网络爬虫,希望对你们有帮助! 一.你知道什么是 ...

  8. 基于python的影评数据分析_基于Python聚焦型网络爬虫的影评获取技术

    龙源期刊网 http://www.qikan.com.cn 基于 Python 聚焦型网络爬虫的影评获取技 术 作者:郭向向 郑嘉慧 苗学芹 来源:<时代金融> 2019 年第 11 期 ...

  9. python如何在网络爬虫程序中使用多线程(threading.Thread)

    python如何在网络爬虫程序中使用多线程 一.多线程的基础知识 二.在网络爬虫中使用多线程 2.1 从单线程版本入手 2.2 将单线程版本改写为多线程版本 2.3 运行多线程版本程序 2.4 将多线 ...

  10. 用python爬虫下载视频_使用Python编写简单网络爬虫抓取视频下载资源

    我第一次接触爬虫这东西是在今年的5月份,当时写了一个博客搜索引擎,所用到的爬虫也挺智能的,起码比电影来了这个站用到的爬虫水平高多了! 回到用Python写爬虫的话题. Python一直是我主要使用的脚 ...

最新文章

  1. java怎么删除List中的指定元素
  2. 微信支付通知 php,微信支付开发交易通知实例
  3. 2016.07.17-18 集合方法
  4. Zoom的Web客户端与WebRTC有何不同?
  5. 7-1 活动选择问题 (25 分)(思路+详解+扩展)宝 今天你AC了吗!!!
  6. 微软power bi_Microsoft Power Platform快速概述
  7. java 复印件效果_简历复印—原型模式
  8. [c++]常对象的特点
  9. Eclipse热部署JSP
  10. JavaScript和HTML及CSS的通俗解释
  11. Linux文件传输与mysql数据库安装
  12. DOS MASM 安装
  13. 太可爱啦!程序员把电脑病毒当宠物养
  14. 2022年CISP考试题库下载
  15. 万花筒の图片服务 动静分离
  16. 电脑查找电子书资源,speedceo浏览器下载PDF文件阅读分享
  17. uc浏览器的navigator.userAgent
  18. 讯飞sdk语音合成测试用例(linux版)
  19. 国嵌Linux视频驱动开发
  20. OutLook中添加、取消送信者禁止

热门文章

  1. ubuntu20.04 基本配置记录 安装 搜狗输入法 QQ 微信
  2. 按键-第1季第9部分-朱有鹏-专题视频课程
  3. linux设备驱动模型-linux驱动开发第5部分-朱有鹏-专题视频课程
  4. Fedora 7安装和配置
  5. Android客户端学习-jdk安装
  6. 学生HTML个人网页作业作品----(画家企业8页)
  7. No gradients provided for any variable, check your graph for ops that do not support gradients
  8. 基于VSM价值流管理提升BizDevOps落地成效
  9. 初学者入门web前端:C#基础知识:函数
  10. 绿联扩展坞拆解_拆解报告:UGREEN 绿联 3A1C 四口多功能扩展坞(带 SD 卡槽版)...