当前位置首页 > 网络营销知识 > 爬取百度百科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() 确认是否还有未爬取URLhtml_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("%s " % data['url'])
f.write("%s " % data['title'])
f.write("%s " % data['sum ** ry'])
f.write(" ")
f.write("
")
f.write("")
f.write("")
分析导图分析导图代码和导图文件链接:
>note.youdao.com/noteshare?id=9553ce3d23b4d5ab4090eafa
网页编码
查看
中标签的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() 确认是否还有未爬取URLhtml_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) != 0html_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_datahtml_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("%s | " % data['url']) f.write("%s | " % data['title']) f.write("%s | " % data['sum ** ry']) f.write("
代码和导图文件链接:
>note.youdao.com/noteshare?id=9553ce3d23b4d5ab4090eafa
Copyright © 深圳市三六五信息技术有限公司 2018 版权所有 粤ICP备14065814号

18664972870
