网页抓取数据百度百科(抓取策略确定目标:确定抓取哪个网站的哪些页面的哪部分数据)
优采云 发布时间: 2021-12-18 07:01网页抓取数据百度百科(抓取策略确定目标:确定抓取哪个网站的哪些页面的哪部分数据)
爬取策略
确定目标:确定要抓取哪个网站的哪个页面的哪一部分数据。本例抓取百度百科python入口页面和python相关入口页面的标题和介绍。
分析目标:分析要爬取的URL的格式,限制爬取的范围。分析要捕获的数据的格式。在本例中,我们将分析标题和介绍这两个数据所在的标签格式。分析要爬取的页面编码的格式。在页面解析器部分,您必须指定页面编码才能进行正确的分析。
编写代码:在网页解析器部分,要使用分析目标得到的结果。
执行爬虫:数据抓取。
分析目标
1、网址格式
进入百度百科的python词条页面,页面上相关词条的链接比较统一,多为/view/xxx.htm。
2、数据格式
标题位于 lemmaWgt-lemmaTitle-title 类下的 h1 子标签中,介绍位于 lemma-summary 类下。
3、编码格式
查看页面编码格式,utf-8。
经过以上分析,结果如下:
代码编写项目结构
在sublime下新建一个文件夹baike-spider作为项目根目录。
创建spider_main.py 作为爬虫通用调度器。
创建一个新的 url_manger.py 作为 url 管理器。
创建一个新的 html_downloader.py 作为 html 下载器。
创建一个新的 html_parser.py 作为 html 解析器。
创建一个新的 html_outputer.py 作为写出数据的工具。
最终的项目结构如下:
蜘蛛主.py
# coding:utf-8
import url_manager, html_downloader, html_parser, html_outputer
class SpiderMain(object):
def __init__(self):
self.urls = url_manager.UrlManager()
self.downloader = html_downloader.HtmlDownloader()
self.parser = html_parser.HtmlParser()
self.outputer = html_outputer.HtmlOutputer()
def craw(self, root_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 == 10:
break
count = count + 1
except:
print('craw failed')
self.outputer.output_html()
if __name__=='__main__':
root_url = 'http://baike.baidu.com/view/21087.htm'
obj_spider = SpiderMain()
obj_spider.craw(root_url)
url_manger.py
# coding:utf-8
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_downloader.py
# coding:utf-8
import urllib.request
class HtmlDownloader(object):
def download(self, url):
if url is None:
return None
response = urllib.request.urlopen(url)
if response.getcode() != 200:
return None
return response.read()
html_parser.py
# coding:utf-8
from bs4 import BeautifulSoup
import re
from urllib.parse import urljoin
class HtmlParser(object):
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']
new_full_url = urljoin(page_url, new_url)
# print(new_full_url)
new_urls.add(new_full_url)
#print(new_urls)
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()
# <p class="lemma-summary" label-module="lemmaSummary">
summary_node = soup.find('p', class_='lemma-summary')
res_data['summary'] = summary_node.get_text()
# print(res_data)
return res_data
def parse(self, page_url, html_cont):
if page_url is None or html_cont is None:
return
soup = BeautifulSoup(html_cont, 'html.parser')
# print(soup.prettify())
new_urls = self._get_new_urls(page_url, soup)
new_data = self._get_new_data(page_url, soup)
# print('mark')
return new_urls, new_data
html_outputer.py
# coding:utf-8
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):
fout = open('output.html','w', encoding='utf-8')
fout.write('')
fout.write('')
fout.write('')
for data in self.datas:
fout.write('')
fout.write('%s' % data['url'])
fout.write('%s' % data['title'])
fout.write('%s' % data['summary'])
fout.write('')
fout.write('')
fout.write('')
fout.write('')
fout.close()
跑
在命令行下,执行python spider_main.py。
编码问题
问题描述:UnicodeEncodeError:'gbk' codec can't encode character 'xa0' in position ...
在Python写文件的时候,或者把网络数据流写到本地文件的时候,大多数情况下都会遇到这个问题。关于如何解决这个问题,网上有很多类似的文章,但无非就是编码和解码。这是问题的真正原因吗?不。很多时候,我们使用decode和encode,尝试了各种编码,utf8、utf-8、gbk、gb2312等,所有的编码都试过了,但是还是出现错误,让人崩溃。
windows下写python脚本有严重的编码问题。在将网络数据流写入文件时,我们会遇到几种编码:
1、#encoding='XXX'
这里的编码(即python文件第一行的内容)是指python脚本文件本身的编码,无所谓。只要XXX的编码和文件本身是一样的。
例如,可以在notepad++的“格式”菜单中设置各种编码。这时候需要确保本菜单中设置的编码与编码XXX一致。如果不同,就会报错。
2、网络数据流的编码
比如获取一个网页,那么网络数据流的编码就是网页的编码。需要使用decode解码成unicode编码。
3、目标文件的编码
将网络数据流写入新文件,文件代码如下:
fout = open('output.html','w')
fout.write(str)
在Windows下,新建文件的默认编码是gbk,python解释器会使用gbk编码来解析我们的网络数据流str。但是, str 是解码后的 unicode 编码。这会导致解析失败和上述问题。解决办法是改变目标文件的编码:
fout = open('output.html','w', encoding='utf-8')
操作结果
更多Python抓取百度百科数据文章,请关注PHP中文网!
免责声明:本文原创发表于php中文网。转载请注明出处。感谢您的尊重!如果您有任何疑问,请与我们联系