热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

最近学习Python
廖雪峰老师的Python 3教程
想要用项目练练手。Python网络爬虫看起来是不错的练手项目,于是着手学习爬虫的制作。
一开始并没有什么头绪,直到看到了慕课网的Python爬虫教程。
这个教程基于python2,但是给了我爬虫的基本思路。接着我用python3写了该教程上的百度百科(弱智)爬虫。

百度百科(弱智)爬虫 基于python3

功能简介

爬取与某个百科页面相关的几百个百科页面。用的是深度优先搜索,所以会搜出很多莫名其妙的词条。实际上这个爬虫并没有什么卵用,只是拿来学习练手。

爬虫框架

有一个主程序和四个模块。
四个模块分别是

  1. url管理器:管理url
  2. html下载器:用request,下载网页的html代码
  3. html解析器:用BeautifulSoup4,解析下载下来的html代码,获得词条的标题和简介
  4. html输出器:输出为一个html,用表格的形式表现最终的数据

爬虫代码

主程序

# spider_main.py
from baike_spider import url_manager
from baike_spider import html_downloader
from baike_spider import html_parser
from baike_spider import html_outputer

class SpiderMain(object):
def __init__(self):
# init all objects
self.urls = url_manager.UrlManager()
self.downloader = html_downloader.HtmlDownloader()
self.parser = html_parser.HtmlParser()
self.outputer = html_outputer.HtmlOutputer()

def crawl(self, root_url):
count = 1
# add root_url into url_manager
self.urls.add_new_url(root_url)
# start loop
while self.urls.has_new_url():
try:
new_url = self.urls.get_new_url()
print('crawling %d : %s' % (count, new_url))
html_cOnt= self.downloader.download(new_url)
new_urls, new_data = self.parser.parse(new_url, html_cont) # get new urls and data
self.urls.add_new_urls(new_urls)
self.outputer.collect_data(new_data) # collect data
if count == 300:
break
count = count + 1
except:
print('crawl failed.')

self.outputer.output_html()


if __name__=='__main__':
root_url = 'http://baike.baidu.com/view/1927.htm'
obj_spider = SpiderMain()
obj_spider.crawl(root_url) # start spider

url管理器

# url_manager.py
class UrlManager(object):
def __init__(self):
self.new_urls = set()
self.old_urls = set()

def add_new_url(self, url):
if url is None:
return
if url not in self.new_urls and url not in self.old_urls:
self.new_urls.add(url)

def add_new_urls(self, urls):
if urls is None or len(urls) == 0:
return
for url in urls:
self.add_new_url(url)

def has_new_url(self):
return len(self.new_urls) != 0

def get_new_url(self):
new_url = self.new_urls.pop()
self.old_urls.add(new_url)
return new_url

html下载器

# html_downloader
from urllib import request

class HtmlDownloader(object):
def download(self, url):
if url is None:
return None
respOnse= request.urlopen(url)
if response.status != 200:
return None
data = response.read()
return data.decode('utf-8')

html解析器

# html_parser
from bs4 import BeautifulSoup
import re
from urllib.parse import urljoin

class HtmlParser(object):
def parse(self, page_url, html_cont):
if page_url is None or html_cont is None:
return
try:
soup = BeautifulSoup(html_cont, 'html.parser', from_encoding='utf-8')
except ValueError as e:
print('except:', e)
# parse
new_urls = self._get_new_urls(page_url, soup)
new_data = self._get_new_data(page_url, soup)
return new_urls, new_data
# parse new urls
def _get_new_urls(self, page_url, soup):
new_urls = set()
# /view/123.htm
links = soup.find_all('a', href = re.compile(r"/view/\d+\.htm"))
for link in links:
new_url = link['href'] # get link
new_full_url = urljoin(page_url, new_url)
new_urls.add(new_full_url)
return new_urls

# parse title and summary
def _get_new_data(self, page_url, soup):
res_data = {}

# url
res_data['url'] = page_url

#

#

星际争霸Ⅱ


title_node = soup.find('dd', class_='lemmaWgt-lemmaTitle-title',).find('h1')
res_data['title'] = title_node.get_text()

#

summary_node = soup.find('div', class_='lemma-summary')
res_data['summary'] = summary_node.get_text()
print('res_data[\'summary\'] = ', res_data['summary'])
return res_data

html输出器

# html_outputer
class HtmlOutputer(object):

def __init__(self):
# a list to maintain datas
self.datas = []

def collect_data(self, data):
if data is None:
return
self.datas.append(data)

def output_html(self):
fout = open('output.html', 'w', encoding='utf-8')

fout.write('')
fout.write('') # important
fout.write('')
fout.write('')

# python default:unicode
for data in self.datas:
fout.write('')
fout.write('' % data['url'])
fout.write('' % data['title'])
fout.write('' % data['summary'])
fout.write('')

fout.write('
%s%s%s
'
)
fout.write('')
fout.write('')

fout.close()

输出的结果示例

http://baike.baidu.com/view/1927.htm 星际争霸 《星际争霸》(英语:StarCraft)是暴雪娱乐制作发行的一款即时战略游戏。这是星际争霸系列游戏的第一部作品,于1998年3月31日正式发行。游戏拥有3部资料片,但是正式发行的只有《母巢之战》。其续作《星际争霸II:自由之翼》已于2010年7月27日发行。《星际争霸》使用《魔兽争霸Ⅱ》引擎,但不同的是融合了三个截然不同的种族:Protoss,Zerg和Terran,他们各自有着迥然不同的战斗单位与科技树。
http://baike.baidu.com/view/174999.htm 吉尼斯世界纪录大全 吉尼斯世界纪录大全于1955年问世,集世界上最好、最坏、最美、最怪、最惨、最伟大的事物,收录了许多光怪陆离、难以想象的纪录。
http://baike.baidu.com/view/293873.htm 碉堡 碉堡是一个网络流音乐,由屌爆演化而来,主要有“震惊了”、“悲剧了”、“非常牛逼”几种意思,不同场合下意义也不同。
http://baike.baidu.com/view/969702.htm DuGalle DuGalle是暴雪开发的即时战略游戏星际争霸(StarCraft)中的角色。(2436年-2500年3月24日) Gerard DuGalle上将是来自地球的Terran,隶属UED(United Earth Directorate)。
http://baike.baidu.com/view/3306588.htm 兵营
http://baike.baidu.com/view/368419.htm 黑暗执政官 黑暗执政官是星际争霸中神族的部队,在它们漫长的放逐过程中面对着各种各样的挑战。在这个过程中,它们不停地与命运做抗争,改进自己的武器技能,并把自己的生理形态转化成更适应周围恶劣的环境,最终就产生了黑暗执政官。
http://baike.baidu.com/view/565476.htm 金甲虫 金甲虫创于一九九六年,店铺遍及四川、贵州、云南、重庆等四省十一市三十余个县,开业十五年无一假货,以“到金甲虫,买正宗货”闻名遐迩。[1]


推荐阅读
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
author-avatar
北斗盖全球
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有