【Python自动化】多线程BFS站点结构爬虫代码,支持中断恢复,带注释

简介: 【Python自动化】多线程BFS站点结构爬虫代码,支持中断恢复,带注释
from collections import deque
from urllib.parse import urljoin, urlparse
import requests
from pyquery import PyQuery as pq
import re
from EpubCrawler.util import request_retry
import traceback
from functools import reduce
from concurrent.futures import ThreadPoolExecutor
# 子线程入口,包装`get_next`并添加异常处理和结果传递
def tr_get_next_safe(i, url, res, args):
    try:
        print(url)
        ns = get_next(url, args)
        res[i] = ns
    except:
        traceback.print_exc()
def get_next(url, args):
    # 请求该网页
    # 这里是带重试的 GET
    # 可以看我其它项目源码,也可以自己写一个。
    html = request_retry(
        'GET', url, 
        retry=args.retry,
        proxies=args.proxy,
    ).text
    if not html: return []
    # 解析其中所有链接的`href`属性
    rt = pq(html)
    el_links = rt('a')
    links = [
        urljoin(url, pq(el).attr('href').strip()) 
        for el in el_links
        if pq(el).attr('href')
    ]
    # 过滤掉其它网站的链接
    hostname = urlparse(url).hostname
    links = [
        l for l in links 
        if urlparse(l).hostname == hostname
    ]
    # print(f'url: {url}\nnext: {links}\n')
    return links
def whole_site(args):
    # `args.site`:`str`,站点网址
    # `args.proxy`:`str`,代理地址,默认`None`
    # `args.retry`:`int`,重试次数
    # `args.threads`:`int`,线程数
    site = args.site
    if args.proxy: 
        args.proxy = {'http': args.proxy, 'https': args.proxy}
    pref = re.sub(r'[^\w\-\.]', '-', site)
    # 结果保存文件和历史记录文件
    res_fname = f'{pref}.txt'
    rec_fname = f'{pref}_rec.txt'
    ofile = open(res_fname, 'a', encoding='utf8')
    rec_file = open(rec_fname, 'a+', encoding='utf8')
    # 判断记录文件是否有记录
    if rec_file.tell() != 0:
        # 读取所有行,过滤空行
        rec_file.seek(0, 0)
        rec = rec_file.read().split('\n')
        rec = [l for l in rec if l.strip()]
        # -1 的数量是弹出操作的数量,从队列前方移除指定数量的条目
        pop_count = rec.count('-1')
        q = deque([l for l in rec if l != "-1"][pop_count:])
        vis = set(rec)
    else:
        # 初始化队列和已访问集
        q = deque([site])
        vis = set([site])
        rec_file.write(site + '\n')
    pool = ThreadPoolExecutor(args.threads)
    while q:
        # 取出指定数量的链接
        pop_cnt = min(len(q), args.threads)
        urls = [q.popleft() for _ in range(pop_cnt)]
        # 调用子线程获取引用
        nexts = [[] for _ in range(pop_cnt)]
        hdls = []
        for i, url in enumerate(urls):
            h = pool.submit(tr_get_next_safe, i, url, nexts, args)
            hdls.append(h)
        for h in hdls: h.result()
        # 过滤空项、合并、去重
        nexts = [n for n in nexts if n]
        nexts = set(reduce(lambda x, y: x + y, nexts, []))
        # 这里可以过滤常见文件后缀,比如 PDF、DOC 等等
        # nexts = (u for u in nexts if not u.endswith('.xml'))
        # 将本次迭代结果更新到磁盘
        # -1 表示弹出元素
        for url in urls:
            ofile.write(url + '\n')
            rec_file.write('-1\n')
        # 将没有访问的引用标记访问,并更新到队列
        for n in nexts:
            if n not in vis:
                vis.add(n)
                q.append(n)
                rec_file.write(n + '\n')
    ofile.close()
    rec_file.close()
相关文章
|
数据采集 存储 JSON
Python爬取知乎评论:多线程与异步爬虫的性能优化
Python爬取知乎评论:多线程与异步爬虫的性能优化
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
数据采集 测试技术 C++
无headers爬虫 vs 带headers爬虫:Python性能对比
无headers爬虫 vs 带headers爬虫:Python性能对比
|
11月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
Python
自动化微信朋友圈:Python脚本实现自动发布动态
本文介绍如何使用Python脚本自动化发布微信朋友圈动态,节省手动输入的时间。主要依赖`pyautogui`、`time`、`pyperclip`等库,通过模拟鼠标和键盘操作实现自动发布。代码涵盖打开微信、定位朋友圈、准备输入框、模拟打字等功能。虽然该方法能提高效率,但需注意可能违反微信使用条款,存在风险。定期更新脚本以适应微信界面变化也很重要。
1715 61
自动化微信朋友圈:Python脚本实现自动发布动态
|
数据采集 存储 Web App开发
多线程爬虫优化:快速爬取并写入CSV
多线程爬虫优化:快速爬取并写入CSV
|
数据采集 机器学习/深度学习 监控
代理IP并发控制:多线程爬虫的加速引擎
在数据采集领域,多线程爬虫结合代理IP并发控制技术,有效突破反爬机制。通过动态代理池与智能并发策略,显著提升采集效率并降低封禁率,成为高效数据抓取的关键方案。
370 0
|
数据采集 存储 监控
Python 原生爬虫教程:网络爬虫的基本概念和认知
网络爬虫是一种自动抓取互联网信息的程序,广泛应用于搜索引擎、数据采集、新闻聚合和价格监控等领域。其工作流程包括 URL 调度、HTTP 请求、页面下载、解析、数据存储及新 URL 发现。Python 因其丰富的库(如 requests、BeautifulSoup、Scrapy)和简洁语法成为爬虫开发的首选语言。然而,在使用爬虫时需注意法律与道德问题,例如遵守 robots.txt 规则、控制请求频率以及合法使用数据,以确保爬虫技术健康有序发展。
1695 31
|
数据采集 存储 Java
多线程Python爬虫:加速大规模学术文献采集
多线程Python爬虫:加速大规模学术文献采集
|
SQL 缓存 分布式数据库
【赵渝强老师】达梦数据库的线程结构
达梦数据库采用单进程、多线程结构,利用对称服务器架构实现高效资源利用与可扩展性。其核心线程类型包括监听线程(管理客户端连接)、I/O线程(处理数据页读写)、工作线程(执行数据操作)、调度线程(定时任务管理)和日志刷新线程(确保REDO日志刷盘)。通过合理分工与同步机制,达梦数据库实现了高性能与稳定性。视频讲解进一步详细介绍了各线程的功能与协作方式。
480 1
【赵渝强老师】达梦数据库的线程结构

热门文章

最新文章

推荐镜像

更多