专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
Python中文社区  ·  超爆回报2682%!轻松复制这个简单暴利的量 ... ·  昨天  
Python爱好者社区  ·  刚刚!微信 DeepSeek ... ·  昨天  
Python爱好者社区  ·  Python接入DeepSeek,太强了! ·  2 天前  
Python爱好者社区  ·  梁文锋导师项志宇引关注,个人主页满满都是对团 ... ·  3 天前  
Python中文社区  ·  马斯克一条推特,股价狂飙?AI量化模型揭秘背 ... ·  4 天前  
51好读  ›  专栏  ›  Python开发者

Python 抓取百度百科数据

Python开发者  · 公众号  · Python  · 2017-02-14 21:11

正文

(点击 上方蓝字 ,快速关注我们)


来源:voidking

segmentfault.com/a/1190000008241040

如有好文章投稿,请点击 → 这里了解详情


前言


本文整理自《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 ,







请到「今天看啥」查看全文