资讯专栏INFORMATION COLUMN

Python抓取百度百科数据

loostudy / 1762人阅读

摘要:前言本文整理自慕课网开发简单爬虫,将会记录爬取百度百科词条相关页面的整个过程。本实例抓取百度百科词条页面以及相关词条页面的标题和简介。分析目标格式进入百度百科词条页面,页面中相关词条的链接比较统一,大都是。

前言

本文整理自慕课网《Python开发简单爬虫》,将会记录爬取百度百科“python”词条相关页面的整个过程。

抓取策略


确定目标:确定抓取哪个网站的哪些页面的哪部分数据。本实例抓取百度百科python词条页面以及python相关词条页面的标题和简介。
分析目标:分析要抓取的url的格式,限定抓取范围。分析要抓取的数据的格式,本实例中就要分析标题和简介这两个数据所在的标签的格式。分析要抓取的页面编码的格式,在网页解析器部分,要指定网页编码,然后才能进行正确的解析。
编写代码:在网页解析器部分,要使用到分析目标得到的结果。
执行爬虫:进行数据抓取。

分析目标

1、url格式
进入百度百科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,作为写出数据的工具。
最终项目结构如下图:

spider_main.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() #
summary_node = soup.find("div", 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("" % data["url"])
            fout.write("" % data["title"])
            fout.write("" % data["summary"])
            fout.write("")

        fout.write("
%s%s%s
") fout.write("") fout.write("") fout.close()
运行

在命令行下,执行python spider_main.py

编码问题

问题描述:UnicodeEncodeError: "gbk" codec can"t encode character "xa0" in position ...

使用Python写文件的时候,或者将网络数据流写入到本地文件的时候,大部分情况下会遇到这个问题。网络上有很多类似的文章讲述如何解决这个问题,但是无非就是encode,decode相关的,这是导致该问题出现的真正原因吗?不是的。很多时候,我们使用了decode和encode,试遍了各种编码,utf8,utf-8,gbk,gb2312等等,该有的编码都试遍了,可是仍然出现该错误,令人崩溃。

在windows下面编写python脚本,编码问题很严重。将网络数据流写入文件时,我们会遇到几个编码:
1、#encoding="XXX"
这里(也就是python文件第一行的内容)的编码是指该python脚本文件本身的编码,无关紧要。只要XXX和文件本身的编码相同就行了。
比如notepad++"格式"菜单里面里可以设置各种编码,这时需要保证该菜单里设置的编码和encoding XXX相同就行了,不同的话会报错。

2、网络数据流的编码
比如获取网页,那么网络数据流的编码就是网页的编码。需要使用decode解码成unicode编码。

3、目标文件的编码
将网络数据流写入到新文件,写文件代码如下:

fout = open("output.html","w")
fout.write(str)

在windows下面,新文件的默认编码是gbk,python解释器会用gbk编码去解析我们的网络数据流str,然而str是decode过的unicode编码,这样的话就会导致解析不了,出现上述问题。 解决的办法是改变目标文件的编码:

fout = open("output.html","w", encoding="utf-8")
运行结果


源码分享

https://github.com/voidking/b...

书签

Python开发简单爬虫
http://www.imooc.com/learn/563

The Python Standard Library
https://docs.python.org/3/lib...

Beautiful Soup 4.2.0 文档
https://www.crummy.com/softwa...

Python词条
http://baike.baidu.com/view/2...
http://baike.baidu.com/item/P...

Python3.x爬虫教程:爬网页、爬图片、自动登录
http://www.2cto.com/kf/201507...

使用python3进行优雅的爬虫(一)爬取图片
http://www.jianshu.com/p/6969...

Python UnicodeEncodeError: "gbk" codec can"t encode character 解决方法
http://www.jb51.net/article/6...

Scrapy documentation
https://doc.scrapy.org/en/lat...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38399.html

相关文章

  • 零基础如何学爬虫技术

    摘要:楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,。本文来源知乎作者路人甲链接楚江数据提供网站数据采集和爬虫软件定制开发服务,服务范围涵盖社交网络电子商务分类信息学术研究等。 楚江数据是专业的互联网数据技术服务,现整理出零基础如何学爬虫技术以供学习,http://www.chujiangdata.com。 第一:Python爬虫学习系列教程(来源于某博主:htt...

    KunMinX 评论0 收藏0
  • 爬虫学习之一个简单的网络爬虫

    摘要:概述这是一个网络爬虫学习的技术分享,主要通过一些实际的案例对爬虫的原理进行分析,达到对爬虫有个基本的认识,并且能够根据自己的需要爬到想要的数据。 概述 这是一个网络爬虫学习的技术分享,主要通过一些实际的案例对爬虫的原理进行分析,达到对爬虫有个基本的认识,并且能够根据自己的需要爬到想要的数据。有了数据后可以做数据分析或者通过其他方式重新结构化展示。 什么是网络爬虫 网络爬虫(又被称为网页...

    Anleb 评论0 收藏0
  • Python爬虫学习路线

    摘要:以下这些项目,你拿来学习学习练练手。当你每个步骤都能做到很优秀的时候,你应该考虑如何组合这四个步骤,使你的爬虫达到效率最高,也就是所谓的爬虫策略问题,爬虫策略学习不是一朝一夕的事情,建议多看看一些比较优秀的爬虫的设计方案,比如说。 (一)如何学习Python 学习Python大致可以分为以下几个阶段: 1.刚上手的时候肯定是先过一遍Python最基本的知识,比如说:变量、数据结构、语法...

    liaoyg8023 评论0 收藏0
  • 小程序开发(一):使用scrapy爬虫采集数据

    摘要:用途广泛,可以用于数据挖掘监测和自动化测试。运行下,发现数据全部存到了数据库中。提供了一些接口来查看项目爬虫情况,以及执行或者停止执行爬虫。完成小程序所需要的所有接口的开发,以及使用定时任务执行爬虫脚本。 过完年回来,业余时间一直在独立开发一个小程序。主要数据是8000+个视频和10000+篇文章,并且数据会每天自动更新。 我会整理下整个开发过程中遇到的问题和一些细节问题,因为内容会比...

    mrli2016 评论0 收藏0
  • Python3网络爬虫实战---19、代理基本原理

    摘要:所以使用代理隐藏真实的,让服务器误以为是代理服务器的在请求自己。参考来源由于涉及到一些专业名词知识,本节的部分内容参考来源如下代理服务器维基百科代理百度百科上一篇文章网络爬虫实战和下一篇文章网络爬虫实战使用发送请求 上一篇文章:Python3网络爬虫实战---18、Session和Cookies下一篇文章:Python3网络爬虫实战---20、使用Urllib:发送请求 我们在做爬虫...

    gougoujiang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<