主要抓取的内容有文章标题、链接、文章发布日期,并保存到本地
- URL管理器:负责管理待爬取的网页URL
- 数据下载器:根据URL下载数据
- 数据分析器:分析筛选下载的数据
- 数据保存器:将筛选出的数据保存到文件或数据库
- 调度器:负责整个系统的调度
一、URL管理器
作用是收集、管理URL信息,包括待爬取的URL、已经爬取过的URL,程序urlmanager.py如下
class URLManager(object):
def __init__(self):
# 初始化待爬取URL与已爬取URL集合
self.new_urls = set()
self.old_urls = set()
def save_new_url(self, url):
# 将单条URl保存到待爬取的集合中
if url is not None:
if url not in self.new_urls and url not in self.old_urls:
print('保存新URL:{}'.format(url))
self.new_urls.add(url)
def save_new_urls(self, url_list):
# 批量保持URL
for url in url_list:
self.save_new_url(url)
def get_new_url(self):
# 取出一条未爬取的URL,同时保存到已爬取的URL中
if self.get_new_url_num()>0:
url = self.new_urls.pop()
self.old_urls.add(url)
return url
else:
return None
def get_new_url_num(self):
# 返回未爬取的URL数量
return len(self.new_urls)
def get_old_url_num(self):
# 返回已爬取的URL数量
return len(self.old_urls)
二、数据下载器
作用:根据提供的URL下载网页数据。
程序htmldownloader.py
import requests
class HtmlDownloader:
def download(self, url):
# 判断URL是否为空
if url is None:
return None
else:
print("开始下载数据,网址{0}".format(url))
response = requests.get(url)
# 如果请求成功,则返回网页数据,否则返回None
if response.status_code == 200:
print("下载数据成功")
# 指定使用UTF-8编码
response.encoding = 'utf-8'
return response.text
return None
if __name__=='__main__':
url = 'http://www.bing.com/'
d = HtmlDownloader()
bing_html = d.download(url)
print(bing_html)
三、数据分析器
作用:接收下载到的网页数据,从中提取我们需要的数据。这里使用BeautifulSoup进行页面解析、数据提取。
数据分析器htmlparse.py
from bs4 import BeautifulSoup
from datasave import DataSave
import re
import requests
class HtmlParse:
# 主输出方法,返回提取的URL列表与待保存的数据
def parse_data(self, page_url, data):
print('开始分析提取数据')
if page_url is None or data is None:
return
soup = BeautifulSoup(data, 'lxml')
urls = self.get_urls(soup)
data = self.get_data(page_url, soup)
return urls,data
def get_urls(self,soup):
urls = list()
# 获取科技类文章地址Tag
links = soup.select('a[href*="/tech/"]')
for link in links:
url = link['href']
urls.append(url)
return urls
# 提取文章数据
def get_data(self,page_url, soup):
data = {}
# 文章的地址、标题、发布日期保存到字典中
# 文章URL只是使用参数url
data['url']=page_url
# select_one获取符合条件的第一条
# 获取文章标题
title = soup.select_one('.cnbeta-article>header>h1')
# 获取发布日期
release_data =soup.select_one('.cnbeta-article>header>.meta>span')
# 将数据保存到一个字典变量中
data['title'] = title.get_text()
data['release_data'] = release_data.get_text()
print('文章url:{0}'.format(page_url))
print('数据:{0}'.format(data))
return data
if __name__=='__main__':
url = 'https://www.cnbeta.com/articles/tech/811395.htm'
save = DataSave('D:\\pycharm\\pych\\爬虫\\爬取数据\\file.txt')
response = requests.get(url)
response.encoding='utf-8'
parse = HtmlParse()
u,d = parse.parse_data(url, response.text)
save.save(d)
print(u,d)
四、数据保存器
程序datasave.py
import os
class DataSave:
# 指定数据保存的文件路径
def __init__(self, path):
self.path = path
def save(self, data):
# 判断文件路径是否存在,若不存在,则抛出错误
#if not os.path.exists(self.path):
# raise FileExistsError
# 将数据写入文件中,以追加形式写入文件
with open(self.path,'a') as fp:
print('开始写入数据')
# 加上\n换行写入数据
fp.write(str(data)+'\n')
fp.close()
if __name__=='__main__':
test_data = 'this is a test, \n save it'
save_path = 'D:\\pycharm\\pych\\爬虫\\爬取数据\\file.txt'
ds = DataSave(save_path)
ds.save(test_data)
五、调度器
作用:将所有组件关联起来,起到管理数据流通的作用。
调度器scheduler.py
from datasave import DataSave
from htmldownloader import HtmlDownloader
from htmlparse import HtmlParse
from urlmanager import URLManager
class Scheduler:
def __init__(self,path,root_url,count):
# 初始化各个组件
self.url_manager = URLManager()
self.data_save = DataSave(path)
self.html_parse = HtmlParse()
self.downloader = HtmlDownloader()
self.root_url = root_url
self.count = count
def run_spider(self):
# 先添加一条URL到为爬取URL集合中
self.url_manager.save_new_url(self.root_url)
# 判断:如果未爬取URL集合中还有网址,并且还没有爬取到50篇文章,那么继续爬取
while self.url_manager.get_new_url_num() and self.url_manager.get_old_url_num() < self.count:
try:
# 获取未爬取URL
url = self.url_manager.get_new_url()
# 下载数据
response = self.downloader.download(url)
# 分析数据,返回URL和文章相关数据
new_url, data = self.html_parse.parse_data(url,response)
# 将获取到的URL保存到为爬取URL集合中
self.url_manager.save_new_urls(new_url)
# 保存数据到本地文件
self.data_save.save(data)
print('已经抓取了{0}篇文章'.format(len(self.url_manager.old_urls)))
except Exception as e:
print("本篇文章抓取停止,{0}".format(e))
if __name__=='__main__':
root_url = 'https://www.cnbeta.com/articles/tech/811395.htm'
save_url = 'D:\\pycharm\\pych\\爬虫\\爬取数据\\file.txt'
Spider = Scheduler(save_url, root_url,20)
Spider.run_spider()
最后的爬取结果
{‘url’: ‘https://www.cnbeta.com/articles/tech/811395.htm’, ‘title’: ‘苹果连续12年名列《财富》“全球最受赞赏公司”榜首’, ‘release_data’: ‘2019年01月22日 22:19’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/811395.htm’, ‘title’: ‘苹果连续12年名列《财富》“全球最受赞赏公司”榜首’, ‘release_data’: ‘2019年01月22日 22:19’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1062477.htm’, ‘title’: ‘试用SA 5G:8元套餐网速照样起飞’, ‘release_data’: ‘2020年12月07日 07:22’}
{‘url’: ‘http://www.cnbeta.com/articles/tech/1058045.htm’, ‘title’: ‘Razer雷蛇推出口罩新品:三层百摺式口罩可重复使用’, ‘release_data’: ‘2020年11月25日 15:29’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1063855.htm’, ‘title’: ‘苹果正在官网销售瑜伽运动装备 搭配Fitness+服务’, ‘release_data’: ‘2020年12月09日 23:45’}
{‘url’: ‘http://www.cnbeta.com/articles/tech/1055773.htm’, ‘title’: ‘英特尔为白牌笔记本电脑市场带来NUC M15新套件’, ‘release_data’: ‘2020年11月20日 09:02’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1063635.htm’, ‘title’: ‘乐高发布两款机械组疯狂大脚怪套装’, ‘release_data’: ‘2020年12月09日 13:25’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1064257.htm’, ‘title’: ‘苹果造车芯,剑指特斯拉’, ‘release_data’: ‘2020年12月10日 19:41’}
{‘url’: ‘http://www.cnbeta.com/articles/tech/1058669.htm’, ‘title’: ‘泰国王妃1400张私照遭外泄 都是SD卡惹的祸’, ‘release_data’: ‘2020年11月26日 20:48’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1061769.htm’, ‘title’: ‘四年前卖家狂赌比特币的一家人 现在怎么样了?’, ‘release_data’: ‘2020年12月04日 13:29’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1063727.htm’, ‘title’: ‘专利暗示Apple Glass可仅渲染焦点内容以加速VR体验’, ‘release_data’: ‘2020年12月09日 15:58’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1063337.htm’, ‘title’: ‘3GPP宣布5G Rel-17标准延期半年 2022年6月份冻结’, ‘release_data’: ‘2020年12月08日 20:52’}
{‘url’: ‘http://www.cnbeta.com/articles/tech/1063973.htm’, ‘title’: ‘供应商责任团队前成员披露苹果对供应链存在违反劳动法行为知情’, ‘release_data’: ‘2020年12月10日 09:14’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1063657.htm’, ‘title’: ‘5G R17冻结时间再次推迟半年:原因为何?影响几何?’, ‘release_data’: ‘2020年12月09日 13:48’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1061085.htm’, ‘title’: ‘TikTok:Bell Poarch对口型‘M to the B’视频为今年最热门病毒视频’, ‘release_data’: ‘2020年12月03日 07:57’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1062559.htm’, ‘title’: ‘[图]英特尔和微软大力推动PRM,替代SMM执行相关代码’, ‘release_data’: ‘2020年12月07日 09:54’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1064399.htm’, ‘title’: ‘邬贺铨:可用“频谱区块链”解决5G频谱短缺问题’, ‘release_data’: ‘2020年12月11日 07:55’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1061215.htm’, ‘title’: ‘“超极本”概念回归 新认证如何拓展轻薄本更多生产力?’, ‘release_data’: ‘2020年12月03日 10:54’}
{‘url’: ‘http://www.cnbeta.com/articles/tech/1064111.htm’, ‘title’: ‘外媒预计苹果汽车2024年到2025年推出 届时库克仍有望是CEO’, ‘release_data’: ‘2020年12月10日 13:42’}
{‘url’: ‘http://www.cnbeta.com/articles/tech/1063725.htm’, ‘title’: ‘无惧6亿欠款 罗永浩公布2020年带货成绩:单月最高5.2亿’, ‘release_data’: ‘2020年12月09日 15:50’}
{‘url’: ‘https://www.cnbeta.com/articles/tech/1063725.htm’, ‘title’: ‘无惧6亿欠款 罗永浩公布2020年带货成绩:单月最高5.2亿’, ‘release_data’: ‘2020年12月09日 15:50’}