笔趣阁分布式flask爬虫

通过flask+mongo+requests实现一个主从分布式爬虫
一:分布式爬虫介绍
1、对等分布式:每台机器上的的爬虫都一致
  • 无论那台机器掉线,都不会影响其他机器的爬虫
  • 可以根据需求动态的增/删计算机和爬虫的数量

试用场景:非递进关系网站

2、主从分布式:不同的机器类型做不同的动作,例如主机器只做详情url的提取,从机器只做详情页的解析
  • 分工明确,有效的控制资源消耗

试用场景:递进关系的网站

二:本程序实现构想

读书网站为目录页+书本章节页+内容页,因此主从的分布式架构比较适合

整体架构如图所示:

本例中的数据存储通过flask来转换进行,从机不需要安装mongo,只需要能访问主机开启的flask就行

3、实现(以目录页爬虫为例)

爬虫的代码比较简单就不放了。有兴趣的可以去github上找

关键说说怎么通过了flask将所有的访问的数据进行存储。

首先在主机上开启flask的服务,服务中有:插入任务、插入数据等接口

@app.route('/insert_task', methods=['POST'])
def insert_task():
    """
    当存在url时不更新
    @return:
    """
    rj = request.get_json()
    coll_name = rj['coll_name']
    data = rj['data']
    if not db[coll_name].find_one({'url': data['url']}):
        db[coll_name].insert_one(data)
    return 'OK'

在每个从机中需要插入数据的时候,进行一层调用,原本直接存储的数据,通过flask来进行指定存储。

            for item in items:
                novel_url = item.xpath('./li[@class="two"]/a/@href')[0]
                name = item.xpath('./li[@class="two"]/a/text()')[0][:-4]
                catalog = {
                    "name": name,
                    "url": novel_url
                }
                # 数据插入点,调用的是下面函数
                insert_task("catalog_task", catalog)
def insert_task(coll_name, task, logger=None):
    """
    通过控制不同的coll_name实现对不同集合的写入
    @param coll_name:
    @param task:
    @param logger:
    @return:
    """
    while True:
        try:
            url = '{}/insert_task'.format(HOST)
            data = {
                'coll_name': coll_name,
                'data': task
            }
            res = requests.post(url, json=data)
            if res.status_code != 200:
                raise Exception('status_code:{}'.format(res.status_code))
            break
        except Exception as e:
            trace = traceback.format_exc()
            info = 'error:{},trace:{}'.format(str(e), trace)
            logger.error(info)
            time.sleep(5)
4、效果展示

catalog为目录集合,catalog_task,为目录任务集合,novels为章节信息集合,novels_task为章节信息任务集合,chapter为章节内容集合。

github地址:https://github.com/tuhou/spider_practice

小说爬虫可以使用不同的编程语言和工具实现,以下是Python和C++ Qt两种实现方式的介绍: ### Python实现 Python可以利用`BeautifulSoup`库的`select`方法来实现小说爬虫,根据输入的小说网址爬取整个小说并保存到txt文件。以下是一个简单示例思路: ```python import requests from bs4 import BeautifulSoup def get_novel_content(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(url, headers=headers) response.encoding = response.apparent_encoding soup = BeautifulSoup(response.text, 'html.parser') # 这里需要根据网页实际结构调整选择器 chapter_content = soup.select_one('#content').text return chapter_content def save_to_txt(content, filename): with open(filename, 'a', encoding='utf-8') as f: f.write(content) # 示例小说目录页URL,需替换为实际URL novel_url = 'https://example.com/novel' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(novel_url, headers=headers) response.encoding = response.apparent_encoding soup = BeautifulSoup(response.text, 'html.parser') # 这里需要根据网页实际结构调整选择器获取章节链接 chapter_links = soup.select('.listmain a') for link in chapter_links: chapter_url = 'https://example.com' + link['href'] # 拼接完整章节URL chapter_content = get_novel_content(chapter_url) save_to_txt(chapter_content, 'novel.txt') ``` 此代码只是一个简单示例,实际使用时需要根据网页的具体结构调整选择器。 ### C++ Qt实现 使用C++和Qt创建的小说爬虫,可利用Qt的网络访问类和正则表达式来获取和处理网页内容,并将小说章节保存到本地文本文件。不过代码量相对较多,这里给出简单思路: ```cpp #include <QCoreApplication> #include <QNetworkAccessManager> #include <QNetworkRequest> #include <QNetworkReply> #include <QRegularExpression> #include <QFile> #include <QTextStream> // 处理网络响应 void handleNetworkResponse(QNetworkReply *reply, const QString &filename) { if (reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); QString html = QString::fromUtf8(data); // 使用正则表达式提取小说内容 QRegularExpression re("<div id=\"content\">(.*?)</div>"); QRegularExpressionMatch match = re.match(html); if (match.hasMatch()) { QString content = match.captured(1); // 保存到文件 QFile file(filename); if (file.open(QIODevice::Append | QIODevice::Text)) { QTextStream out(&file); out << content; file.close(); } } } reply->deleteLater(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QNetworkAccessManager manager; // 示例小说章节URL,需替换为实际URL QNetworkRequest request(QUrl("https://example.com/chapter")); QNetworkReply *reply = manager.get(request); QObject::connect(reply, &QNetworkReply::finished, [reply]() { handleNetworkResponse(reply, "novel.txt"); }); return a.exec(); } ``` 同样,此代码中的正则表达式和URL需要根据实际网页结构和具体小说URL进行调整。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值