全网文章 采集(简单来说就是基于Scrapy框架(爬虫框架)+Gerapy框架)
优采云 发布时间: 2021-12-02 11:04全网文章 采集(简单来说就是基于Scrapy框架(爬虫框架)+Gerapy框架)
介绍
中国网的很多小伙伴都不知道,它是一家与新华网、人民网同名的全国性新闻媒体机构。有幸参与了863项目的舆论工程。现在很多企业舆论项目都是从这套内容衍生出来的。而且很多民意项目衍生出来的项目,都会涉及到数据采集的工作。简单来说,就是基于现有业务,从舆情内容数据中提取响应内容。
结合舆情系统的结构,复现了一组爬虫数据采集的结构。由于该项目历史悠久,具体开发内容和具体*敏*感*词*法不得而知。结合话题相关内容,用Python转载了一组舆情。该系统被企业的某些项目所使用。本系统的内容将在以后更新。今天主要讲一下data采集的思路和简单功能的实现。
耐心看完后,我保证你也能做到
数据采集 项
项目整体复现概念基于Scrapy框架(爬虫框架)+Gerapy框架(爬虫管理框架)。实现分布式数据采集每天根据不同的项目,采集数据在百万级左右。下面是部分实现内容。有兴趣的朋友可以自行尝试更*敏*感*词*的数据。采集。
数据准备
准备目标 URL。由于是项目规定的范围,所涉及的内容仅限于新闻数据。需要组织一个数据源数据库,将部分内容截取成Excel表格。
Pivot 提供简单的数据统计。
Scrapy爬虫框架使用
基于框架就是用通用的方式来进行数据采集,用同一个脚本来组织爬虫的内容,也就是说普通的静态页面直接使用一套通用的算法采集新闻的标题和链接,以及获取文章正文的访问日期。
items.py 定义了获取的字段
class NewsDataItem(scrapy.Item):
title = scrapy.Field() # 新闻标题
url = scrapy.Field() # 原文链接
publishTime = scrapy.Field() # 发布时间
content = scrapy.Field() # 文章正文
new_type = scrapy.Field() # 新闻类别
web_name = scrapy.Field() # 网站名称
channel_name = scrapy.Field() # 频道名称
middlewares.py 随机替换头部和 IP 代理
# 添加Header和IP类
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
from scrapy.utils.project import get_project_settings
settings = get_project_settings()
class RotateUserAgentMiddleware(UserAgentMiddleware):
def process_request(self, request, spider):
referer = request.url
if referer:
request.headers["referer"] = referer
USER_AGENT_LIST = settings.get('USER_AGENT_LIST')
user_agent = random.choice(USER_AGENT_LIST)
if user_agent:
request.headers.setdefault('user-Agent', user_agent)
print(f"user-Agent:{user_agent}")
# 添加随机更换IP代理类(根据实际IP代理情况进行修改获取方式和更改方式)
import random
import sys
import requests
sys.path.append('.')
class MyProxyMiddleware(object):
def process_request(self, request, spider):
url = "这里放购买的代理API地址,进行解析后使用代理访问"
html = requests.get(url).text
ip_list = html.split("\r\n")[:-1]
proxy = random.choice(ip_list)
request.meta['proxy'] = 'http://' + proxy
pipelines.py 数据存储设置
class NewsDataPipeline(object):
def __init__(self):
host = settings["MONGODB_HOST"]
port = settings["MONGODB_PORT"]
dbname = settings["MONGODB_DATABASE"]
collection = settings["MONGODB_COLLECTION"]
username = settings["MONGODB_USER"]
password = settings["MONGODB_PASSWORD"]
# 创建MONGODB数据库链接
client = pymongo.MongoClient(host=host, port=port, username=username, password=password)
# 指定数据库
db = client[dbname]
# 存放数据的数据库表名
self.post = db[collection]
def process_item(self, item, spider):
data = dict(item)
# 数据写入
self.post.insert(data)
return item
settings.py 通用配置,添加数据库信息和headers
# 添加 设置浏览器Header设置,不够用自行添加
USER_AGENT_LIST = [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
......
]
MONGODB_HOST = "localhost" # 数仓IP
MONGODB_PORT = 27017 # 数仓端口号
MONGODB_DATABASE = "" # 数仓数据库
MONGODB_COLLECTION = "" # 数仓数据表单
MONGODB_USER = "" # 数仓验证的用户名
MONGODB_PASSWORD = "" # 数仓验证的用户密码
spider.py 主程序爬取
这里使用的gerapy_auto_extractor的extract_list直接解析列表页面。
# -*- coding: utf-8 -*-
import scrapy
from News_Data.items import NewsDataItem
import pandas as pd
from .parse_detail import ProcessContent
from urllib import parse
from scrapy.utils.project import get_project_settings
from gerapy_auto_extractor.extractors import *
settings = get_project_settings()
class NewsDataSpider(scrapy.Spider):
name = 'News_Data'
allowed_domains = []
def start_requests(self):
# 读取数据
df = pd.read_excel("../../我的数据抓取列表.xlsx", sheet_name="数据列表")
# 数据打乱
df = df.sample(frac=1.0).reset_index(drop=True)
for i in range(len(df)):
data = df.iloc[i].to_dict()
print(data)
# 判断常规网页
if data['动态加载url'] == '-' and data['url 参数'] == '-':
yield scrapy.Request(
url=data["网址"], meta={'data': data, }, callback=self.parse_static
)
def parse_static(self, response):
data = extract_list(response.text)
for each in range(len(data)):
item = NewsDataItem()
item['title'] = data[each]["title"].strip()
item['url'] = parse.urljoin(response.url, data[each]["url"])
item['publishTime'] = ""
item["new_type"] = response.meta["data"]["类别"]
item['web_name'] = response.meta["data"]["网站名称"]
item['channel_name'] = response.meta["data"]["网站频道"]
yield scrapy.Request(item['url'], callback=self.parse_detail, meta={'item': item})
# 具体内容在parse_detail.py中
def parse_detail(self, response):
item = ProcessContent(self, response)
yield item
detail.py 数据详情
这里使用的gerapy_auto_extractor的extract_detail直接解析页面。
<p>def ProcessContent(self, response):
# 设置详情页的内容
item = response.meta['item']
data = extract_detail(response.text)
# 处理详情页的时间,如果始终没有获取到时间默认当天日期
if data["datetime"] is None:
item['publishTime'] = DateTimeProcess_Str(item['publishTime'])
else:
item['publishTime'] = DateTimeProcess_Str(data["datetime"])
# 处理详情页带格式,这里整个页面进行抓取,判断每个页*敏*感*词*体内容的样式
item['content'] = ""
if item['web_name'] == "xxxxxxx":
......
elif item['web_name'] == "中国质量新闻网":
if 'class="content"' in response.text and len(None2Str(item['content']))