Python爬⾍完整案例-爬取百度百科词条信息概述
⼀个完整的爬⾍,⼀般由以下5个组件构成:
1.URL管理器
负责维护待爬取URL队列和已爬取URL队列,必须拥有去重功能。
2.HTML下载器
负责根据调度器从URL管理器中取出的url,下载html页⾯数据
3.HTML解析器
负责解析HTML下载器下载的⽹页数据,从中提取新的url和⽬标数据,并将其返回
4.数据存储器
负责将HTML下载器返回的的数据保存到本地或数据库中
5.调度器
爬⾍的核⼼组件。根据业务流程,调⽤其它组件完成数据抓取。
⼀般情况下,爬⾍的⼊⼝URL在这⾥提供。
源码
⾸先,项⽬结构如下,每个组件使⽤⼀个模块⽂件
1.URL管理器
class UrlManager(object):
"""URL管理器"""
def __init__(self):
# 待爬去url集合
# 已爬取url集合
self.old_urls=set()
def new_urls_size(self):
"""获取新的url数量"""
return w_urls)
def old_urls_size(self):
"""获取已爬取url数量"""
return len(self.old_urls)
def has_new_url(self):
"""判断是否有新的url"""
w_urls_size()
def get_new_url(self):
"""从待爬取url集合中获取⼀个url"""
# 从未爬取url集合中取出并移除⼀个url        new_w_urls.pop()
# 将取出的url添加到已爬取url集合中
self.old_urls.add(new_url)
return new_url
def add_new_url(self,url):
"""添加⼀个新的url到待爬取url集合中"""        if url:
def add_new_urls(self,urls):
"""添加多个个新的url到待爬取url集合中"""        if urls:
for url in urls:
self.add_new_url(url)
2.HTM下载器
import requests
class HtmlDownloader(object):
"""HTML下载器"""
def download(self,url):
if not url:
return None
headers={
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",        }
(url,headers=headers,timeout=5)
if resp.status_code==des.ok:
3.HTML解析器
# !/usr/bin/env python
error parse new# -*- coding:utf-8 -*-
import urllib.parse
from lxml import etree
class HtmlParser(object):
"""HTML解析器"""
def parse(self,url,html):
html_et=etree.HTML(html)
new_urls=self.__get_new_urls(url,html_et)
new_data=self.__get_new_data(html_et)
return new_urls,new_data
def __get_new_urls(self,url,html_et):
"""提取当前词条页⾯下所有相关链接"""
urls=[]
link_list=html_et.xpath('//div[@class="main-content"]//a/@href')
for link in link_list:
if link.startswith('/item/'):
urls.append(urllib.parse.urljoin(base=url,url=link))
return urls
def __get_new_data(self,html_et):
"""提取当前词条的摘要"""
summary=[]
text_list=html_et.xpath('//div[@class="lemma-summary"]//text()')
for text in text_list:
summary.append(text+'\n')
return ''.join(summary)
4.数据存储器
import os
import codecs
class DataStore(object):
"""数据存储器"""
def store(self,data):
"""将数据保存到本地⽂本⽂件中"""
path='../../data'
if not ists(path):
os.makedirs(path)
with codecs.open(filename=os.path.join(path,'python百科词条.txt'),mode='a',encoding='utf-8') as f:            f.write(data+'\n')
5.调度器
"""
爬⾍调度器
"""
import requests
import time
from urlmanager import UrlManager
from htmldownloader import HtmlDownloader
from htmlpaser import HtmlParser
from datastore import DataStore
class Scheduler(object):
def __init__(self):
"""初始化各组件"""
self.urlmanager=UrlManager()
self.htmldownloader=HtmlDownloader()
self.htmlparser=HtmlParser()
self.datastore=DataStore()
def crawl(self,start_url):
try:
# 添加起始url
self.urlmanager.add_new_url(start_url)
# 最多只爬取500个词条数据
while self.urlmanager.old_urls_size()<500:
time.sleep(0.5)
# 从待爬取url集合中提取⼀条url
url=_new_url()
if url:
# 使⽤HTML下载器下载⽹页
html=self.htmldownloader.download(url)
# 使⽤HTML解析器解析⽹页,提取url和摘要信息
new_urls,new_data=self.htmlparser.parse(url,html)
# 将新提取出的url添加到待爬取url集合中
self.urlmanager.add_new_urls(new_urls)
# 将提取出的摘要⽂本保存到本地⽂件中
self.datastore.store(new_data)
print('已爬取{}个词条'.format(self.urlmanager.old_urls_size()))            else:
print("爬取完成")
except requests.RequestException as e:
print('爬取失败',e)
if __name__ == '__main__':
start_url='baike.baidu/item/Python/407313'
scheduler=Scheduler()

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。