互联网+品牌管家

10年营销经验,提供更直接、更有效的网络营销方案

当前位置首页 > 网络营销知识 > 爬取百度百科1000个词条页面

爬取百度百科1000个词条页面

来源 : www.ce365.cn   发布时间 : 2022/3/4 5:42:00

爬取目标:

从Python词条开始,爬取百度百科1000个词条,得到词条url、词条名和词条简介输出保存为html文件。

目标分析:

入口页

Python词条页: >baike.baidu.com/item/Python/407313

URL格式

不同词条URL前半部分相同: >baike.baidu.com/item/,差异仅在后半部分,在页面中解析出‘/item/XXXX’与前半部分拼接即可得到新的URL。

数据格式

新URL:标签href属性匹配/item/XXX解析出新的词条URL词条名:
包含的

标签的文本解析当前页面的词条名词条简介:
标签的文本解析当前页面的词条简介

网页编码

查看中标签的charset属性,确定网页编码为“UTF-8”,与我所用系统Ubuntu和PyCharm一致。

查看网页编码

工具分析:

URL管理

使用set()数据类型,set()数据类型自身有去重的能,可避免加入已爬过的URL。创建两个set(),分别用于保存已爬取过的URL和待爬取的URL。

新解析出的词条URL不完整,只有‘/item/XXXX’部分,可与当前页面URL通过urllib.parse.urljoin()拼接成一个完整的URL。

网页下载

实验中发现百度百科对于爬虫无特殊限制,直接通过URL,使用urllib.request.urlopen()可顺利爬取到1000个词条。

网页解析

需解析的内容包括:新词条URL、词条名和词条简介。

通过BeautifulSoup使用html.parser方法,对应内容的标签名、标签属性可定位解析出内容,其中解析新词条URL定位href属性时需使用正则表达式匹配为'/item/.+',以确定是百科词条的URL。

结果输出

解析出的词条URL、词条名和词条简介保存为一个HTML文档。

代码结构:

spider_ ** in 程序执行入口、爬虫调度器

SpiderMain()

__init__()craw() 调用URL管理、网页下载、网页解析和结果输出

url_ ** nager URL管理

UrlManager()

__init__() 初始化两个set(),分别表示已爬取URL和未爬取URLadd_new_url() 添加未爬取URLadd_new_urls() 批量添加未爬取URLget_new_url() 取出一个未爬取URL并添加至已爬取URLhas_new_url() 确认是否还有未爬取URL

html_downloader 网页下载

HtmlDownloader()

download() 使用urllib.request.urlopen()下载网页内容

html_parser 网页解析

HtmlParser()

__get_new_urls() 根据网页内容,解析出网页中词条URL__get_new_data() 根据网页内容,解析出词条名和词条简介parse() 返回解析出的新URL和词条名、词条简介

html_outputer 结果保存

HtmlOutputer()

__init__() 初始化一个列表,用于存放不同词条页的URL、词条名和词条简介collect_data() 将内容添加至列表output_html() 将列表内容输出至一个HTML文件

完整代码:

spider_ ** in

""" 从百度百科python词条开始,爬取1000个词条页面,得到词条URL、词条名和词条简介,输出并保存为HTML文档 程序入口、爬虫调度器, """ import url_ ** nager, html_downloader, html_parser, html_outputer class SpiderMain(object): def __init__(self): self.urls = url_ ** nager.UrlManager() self.downloader = html_downloader.HtmlDownloader() self.parser = html_parser.HtmlParser() self.outputer = html_outputer.HtmlOutputer() def craw(self, root_url): """调用url管理、网页下载、网页解析和结果输出""" count = 1 self.urls.add_new_url(root_url) while self.urls.has_new_url(): try: new_url = self.urls.get_new_url() print("craw %d : %s" % (count, new_url)) html_cont = self.downloader.download(new_url) new_urls, new_data = self.parser.parse(new_url, html_cont) self.urls.add_new_urls(new_urls) self.outputer.collect_data(new_data) if count == 1000: break count += 1 except Exception as e: print("craw failed", new_url, e) self.outputer.output_html() if __name__ == "__ ** in__": root_url = "#34; obj_spider = SpiderMain() obj_spider.craw(root_url)

url_ ** nager

""" URL管理 """ class UrlManager(object): def __init__(self): """初始化已爬取URL、未爬取URL""" self.new_urls = set() self.old_urls = set() def add_new_url(self, url): """添加未爬取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): """批量添加未爬取URL""" if (urls is None) or (len(urls) == 0): return for url in urls: self.add_new_url(url) def get_new_url(self): """取出未爬取URL并添加至已爬取URL""" new_url = self.new_urls.pop() self.old_urls.add(new_url) return new_url def has_new_url(self): """确认是否还有未爬取URL""" return len(self.new_urls) != 0

html_downloader

""" 网页下载 """ from urllib import request class HtmlDownloader(object): def download(self, url): """使用urllib.request.urlopen()下载网页内容""" if url is None: return None response = request.urlopen(url) if response.getcode() != 200: return None return response.read().decode("utf-8")

html_parser

""" 网页解析 """ from bs4 import BeautifulSoup import re from urllib import parse class HtmlParser(object): new_urls = set() # 解析出的URL def __get_new_urls(self, page_url, soup): """根据网页内容,解析出网页中词条URL""" 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) HtmlParser.new_urls.add(new_full_url) return HtmlParser.new_urls def __get_new_data(self, page_url, soup): """根据网页内容,解析出词条名和词条简介""" res_data = dict() res_data['url'] = page_url title_node = soup.find('dd', class_="lem ** Wgt-lem ** Title-title").find("h1") res_data['title'] = title_node.get_text() sum ** ry_node = soup.find('div', class_="lem ** -sum ** ry") res_data['sum ** ry'] = sum ** ry_node.get_text() return res_data def parse(self, page_url, html_cont): """返回解析出的新URL和词条名、词条简介""" if (page_url is None) or (html_cont is None): return soup = BeautifulSoup(html_cont, 'html.parser', from_encoding="utf-8") new_urls = self.__get_new_urls(page_url, soup) new_data = self.__get_new_data(page_url, soup) return new_urls, new_data

html_outputer

""" 结果保存 """ class HtmlOutputer(object): def __init__(self): self.datas = [] def collect_data(self, data): """将不同词条页URL、词条名和词条简介添加至一个列表""" if data is None: return self.datas.append(data) def output_html(self): """将结果输出为HTML文件""" with open("output.html", 'w') as f: f.write("") f.write("") f.write("") for data in self.datas: f.write("") f.write("" % data['url']) f.write("" % data['title']) f.write("" % data['sum ** ry']) f.write("") f.write("
%s%s%s
") f.write("") f.write("")

分析导图分析导图

代码和导图文件链接:

>note.youdao.com/noteshare?id=9553ce3d23b4d5ab4090eafa

相关标签:

18664972870

与我联系