网页抓取数据百度百科(简单的爬虫架构如上图)

优采云 发布时间: 2022-04-04 08:19

  网页抓取数据百度百科(简单的爬虫架构如上图)

  什么是爬行动物?

  爬虫是一种自动爬取互联网信息的程序,以便更好地利用数据进行相关分析并做出相关决策。

  简单的爬虫架构

  

  如上图所示,这个架构主要分为五个部分:

  1. 爬虫主调度器

  主要用于调度其他模块相互配合获取我们想要的数据

  2. 网址管理器

  主要管理两部分数据:未爬取的url和等待爬取的url数据

  3. 下载器

  从 url manager 中获取未抓取的 ulr,并使用 urllib 中的 request 模块抓取网络数据。

  4. 解析器

  从下载器获取的 html 数据解析出新的 url 和我们要提取的数据。

  5. 出口商

  将我们想要的数据输出到文件中。

  使用第一眼网址管理器:

  #!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Date : 2018-07-15 15:25:55

# @Author : zhulei (zhuleimailname@gmail.com)

# @Link : http://zhuleiblog.com

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

  该模块的主要功能是管理带爬取和爬取的url,其中new_urls指的是要爬取的url,old_urls指的是已经爬取过的url,并且设置了数据结构,可以直接去重。

  2. 下载器:

  #!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Date : 2018-07-15 15:25:01

# @Author : zhulei (zhuleimailname@gmail.com)

# @Link : http://zhuleiblog.com

from urllib import request

class HtmlDownloader(object):

"""Html下载器"""

def download(self, url):

if url is None:

return None

response = request.urlopen(url)

if response.getcode() != 200:

return None

return response.read()

  这个比较简单,直接使用urllib中的request模块爬取数据

  3. 解析器:

  #!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Date : 2018-07-15 15:25:31

# @Author : zhulei (zhuleimailname@gmail.com)

# @Link : http://zhuleiblog.com

import re

from urllib import parse

from bs4 import BeautifulSoup

class HtmlParser(object):

def _get_new_urls(self, page_url, soup):

new_urls = set()

# 计算机程序设计语言

links = soup.find_all('a', href=re.compile(r"/item/"))

for link in links:

new_url = link['href']

new_full_url = parse.urljoin(page_url, new_url)

new_urls.add(new_full_url)

return new_urls

def _get_new_data(self, page_url, soup):

res_data = {}

# url

res_data['url'] = page_url

#

# Python

# (计算机程序设计语言)

# 编辑

# 锁定

#

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

res_data['title'] = title_node.get_text()

#

# Python

# [1]<a class="sup-anchor" name="ref_[1]_21087">&nbsp;</a>

# (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。Python是纯粹的自由软件, 源代码和解释器CPython遵循 GPL(GNU General Public License)协议。Python语法简洁清晰,特色之一是强制用空白符(white space)作为语句缩进。Python具有丰富和强大的库。它常被昵称为胶水语言,能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起。常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写,比如3D游戏中的图形渲染模块,性能要求特别高,就可以用C/C++重写,而后封装为Python可以调用的扩展类库。需要注意的是在您使用扩展类库时可能需要考虑平台问题,某些可能不提供跨平台的实现。7月20日,IEEE发布2017年编程语言排行榜:Python高居首位

# [2]<a class="sup-anchor" name="ref_[2]_21087">&nbsp;</a>

# 。2018年3月,该语言作者在邮件列表上宣布 Python 2.7将于2020年1月1日终止支持。用户如果想要在这个日期之后继续得到与Python 2.7有关的支持,则需要付费给商业供应商。

# [3]<a class="sup-anchor" name="ref_[3]_21087">&nbsp;</a>

#

#

summary_node = soup.find(&#39;div&#39;, class_=&#39;lemma-summary&#39;).find(&#39;div&#39;, class_=&#39;para&#39;)

res_data[&#39;summary&#39;] = summary_node.get_text()

return res_data

def parse(self, page_url, html_content):

if page_url is None or html_content is None:

return

soup = BeautifulSoup(html_content, &#39;html.parser&#39;, from_encoding=&#39;utf-8&#39;)

new_urls = self._get_new_urls(page_url, soup)

new_data = self._get_new_data(page_url, soup)

return new_urls, new_data

  该模块主要解析下载器的数据。解析使用第三方库“BeautifulSoup”。如果没有安装,请先安装:

  点安装beautifulsoup4

  这里需要分析一下我们需要爬取的数据内容。这里我要爬取的内容是:百科词条的标题和介绍

  

  - 首先,我们要看看标题的html标签格式是什么样子的。右击标题“Python”-&gt;勾选,可以看到它的标签如下:

   #

# Python

# (计算机程序设计语言)

# 编辑

# 锁定

#

  可以看出dd标签中的class属性在lemmaWgt-lemmaTitle-title的h1标签中,所以代码很简单:

   title_node = soup.find(&#39;dd&#39;, class_=&#39;lemmaWgt-lemmaTitle-title&#39;).find(&#39;h1&#39;)

res_data[&#39;title&#39;] = title_node.get_text()

  同理,可以找出引言的标注规则。

  4. 出口商:

  class HtmlOutputer(object):

def __init__(self):

self.datas = []

def collect_data(self, data):

if data is None:

return

self.datas.append(data)

def output_html(self):

f_out = None

try:

f_out = open(&#39;output.html&#39;, &#39;w&#39;, encoding=&#39;utf-8&#39;)

f_out.write("")

f_out.write("")

f_out.write("")

for data in self.datas:

f_out.write("")

f_out.write("%s" % data[&#39;url&#39;])

f_out.write("%s" % data[&#39;title&#39;])

f_out.write("%s" % data[&#39;summary&#39;])

f_out.write("")

f_out.write("")

f_out.write("")

finally:

if f_out:

f_out.close()

  这个模块也很简单。它主要存储我们想要的数据,并以html表格的形式输出到文件“output.html”中。不过需要注意的是,由于爬取的内容是中文的,所以一定要指定编码为utf-8,否则会出现乱码。

  5. 最后,我们编写调度器并爬取 1000 个入口数据:

  #!/usr/bin/env python

# -*- coding: utf-8 -*-

# @Date : 2018-07-15 15:23:26

# @Author : zhulei (zhuleimailname@gmail.com)

# @Link : http://zhuleiblog.com

from baike_spider import url_manager, html_downloader, html_parser, html_outputer

class Spider(object):

def __init__(self):

self.url_manager = url_manager.UrlManager()

self.downloader = html_downloader.HtmlDownloader()

self.html_parser = html_parser.HtmlParser()

self.html_outputer = html_outputer.HtmlOutputer()

def craw(self, rootUrl):

count = 1

self.url_manager.add_new_url(rootUrl)

while self.url_manager.has_new_url():

try:

new_url = self.url_manager.get_new_url()

print("craw%d -> %s" % (count, new_url))

content = self.downloader.download(new_url)

new_urls, data = self.html_parser.parse(new_url, content)

self.url_manager.add_new_urls(new_urls)

self.html_outputer.collect_data(data)

if count == 1000:

break

count = count + 1

except:

print(&#39;craw failed&#39;)

self.html_outputer.output_html()

root_url = "https://baike.baidu.com/item/Python/407313"

if __name__ == "__main__":

spider = Spider()

spider.craw(root_url)

  起始 url 是 Python 入口的 url:root_url = ""

  好的,运行调度程序并开始爬取数据。

  看看上次运行的结果:

  存储的文件是一个html文件,找到文件路径用浏览器打开,可以看到下图。

  

  来源链接

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线