一些爬虫代码的解析

news2024/11/16 13:56:21
import requests
from bs4 import BeautifulSoup
import time
import logging
import json
from concurrent.futures import ThreadPoolExecutor
import random

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 目标网页的URL列表
urls = [
    'http://example.com',
    'http://example.org',
    # 更多URL...
]

# 用户代理列表
user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
    # 更多User-Agent...
]

# 代理服务器列表
proxies = [
    {'http': 'http://10.10.1.10:3128', 'https': 'http://10.10.1.10:1080'},
    # 更多代理...
]

# 会话管理
session = requests.Session()

# 爬虫函数
def crawl(url, session):
    try:
        # 设置User-Agent
        session.headers.update({'User-Agent': random.choice(user_agents)})
        
        # 设置代理
        proxy = random.choice(proxies) if proxies else None
        response = session.get(url, timeout=5, proxies=proxy)
        
        # 检查请求是否成功
        if response.status_code == 200:
            logging.info(f'成功访问: {url}')
            # 使用BeautifulSoup解析网页内容
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # 获取网页的<title>标签内容
            title = soup.title.string if soup.title else 'No title'
            logging.info(f'网页标题是: {title}')
            
            # 返回解析结果
            return {
                'url': url,
                'title': title
            }
        else:
            logging.warning(f'访问失败,状态码: {response.status_code}')
    
    except requests.exceptions.RequestException as e:
        logging.error(f'请求错误: {e}')
    except Exception as e:
        logging.error(f'其他错误: {e}')
    return None

# 多线程爬取函数
def multithread_crawl(urls):
    results = []
    with ThreadPoolExecutor(max_workers=10) as executor:
        future_to_url = {executor.submit(crawl, url, session): url for url in urls}
        for future in concurrent.futures.as_completed(future_to_url):
            url = future_to_url[future]
            result = future.result()
            if result:
                results.append(result)
    return results

# 主函数
def main():
    results = multithread_crawl(urls)
    
    # 将结果保存到JSON文件
    with open('results.json', 'w', encoding='utf-8') as f:
        json.dump(results, f, ensure_ascii=False, indent=4)

if __name__ == '__main__':
    main()

BeautifulSoup:用于解析HTML内容

logging:用于记录日志信息

json用来处理JSON数据

ThreadPoolExecutor:来自concurrent.futures模块,用于创建线程池并管理多线程。

一、

logging.basicConfig设置日志的基本配置。

level=logging.INFO,这设置了日志的最低级别。Python的日志级别从低到高有DEBUG、INFO、WARNING、ERROR和CRITICAL。在这个例子中,我们设置级别为INFO,意味着所有重要及以上级别的日志都会被记录。如果设置为DEBUG,则会记录更多的信息,对于调试程序非常有用。

format='%(asctime)s - %(levelname)s - %(message)s': 这是一个字符串,定义了日志的格式。这个格式包含三个部分:

  • %(asctime)s: 这表示日志的时间戳,会自动记录日志消息产生的时间。默认格式是年-月-日 时:分:秒,毫秒

  • %(levelname)s: 这表示日志的级别,如INFOWARNINGERROR等,这有助于快速识别日志消息的严重性。

  • %(message)s: 这是实际的日志消息,即你传递给logging方法(如logging.info()logging.error()等)的消息。

二、

用户代理(User-Agent)

user_agents列表在爬虫中用于存储不同的浏览器用户代理字符串。用户代理(User-Agent)是HTTP请求的一部分,用于告诉服务器发起请求的浏览器类型和版本,以及其他系统信息。在爬虫中使用用户代理的几个目的:

1、模仿浏览器:大多数网站对直接的爬虫访问有限制,使用用户代理可以模拟普通用户浏览器访问,降低被识别为爬虫的风险。

2、提高兼容性:不同的网站可能对不同的浏览器有不同的支持程度,使用常见的用户代理有助于确保爬虫能够正常访问网站的资源。

3、规避反爬措施:一些网站可能通过检测用户代理来确定是否允许访问,使用合法的用户代理可以规避这些反爬措施。

4、随机化:在user_agents列表中存储多个用户代理,并在请求时随机选择,可以进一步降低被服务器封锁的风险。

这个列表中的具体用户代理字符串如下:

"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"

这是一个示例用户代理字符串,表示访问来自Windows10操作系统的64位计算机,使用的是Google Chrome浏览器的58.0.3029.110版本。Safari/537.3部分可能是为了兼容性而添加的,因为AppleWebKit/537.36是WebKit引擎的版本号,而WebKit也是Safari浏览器的引擎。

三、

在Python的requets库中,Session库中,Session对象是一个会话的高级接口,它允许你跨越多个请求保持某些参数。当你使用requests.Session()创建了一个Session实例后,你可以使用这个实例来发送请求,它会自动处理一些会话相关的逻辑。

以下是session对象的一些关键特性:

1、保持Cookies:

使用Session对象发送请求时,它会在同一个实例中自动保持cookies,这意味着,如果你登陆了一个网站并获取了登录cookies,你可以继续使用同一个Session实例来发送后续请求,而无需重复登录。

2、连接池:

Session对象使用连接池来管理与服务器的连接,这意味着后续的请求可以重用现有的连接,从而提高效率。

3、会话头部

你可以为Session设置自定义的HTTP头部,这些头部会自动包含在该Session实例发出的所有请求中。

4、请求重试

Session对象可以配置重试逻辑,以自动处理请求失败的情况。

5、保持请求参数

当你在Session实例上调用请求方法时,你可以指定请求参数,这些参数会与会话中的其他参数合并。

四、

User-Agent设置:通过random.choice(user_agents)选择一个用户代理,然后更新到session的headers中,这有助于模拟浏览器请求,避免被网站识别为爬虫。

代理设置:如果提供了代理列表proxies,则随机选择一个代理并应用到请求中。如果没有代理列表,则不使用代理。

使用session.get方法发起GET请求,设置超时时间5秒。

五、

multithread_crawl函数接收一个包含多个URL的列表urls

使用ThreadPoolExecutor创建一个线程池,max_workers参数设置为10,表示最多可以同时运行10个线程。

有一些改进的建议:

异常处理:在多线程环境中,如果crawl函数中的某个任务因为异常而失败,它可能不会返回任何结果。您可能需要在multithread_crawl函数中添加异常处理逻辑,以确保即使某些任务失败,其他任务也能继续执行。

Session共享:代码示例中没有显示session是如何定义和传递给crawl函数的。如果session是全局的或者在multithread_crawl函数外部创建的,确保它是线程安全的,或者为每个线程创建一个新的session实例。

日志记录:在多线程环境中,日志记录可能会产生竞争条件。确保您的日志记录是线程安全的,或者使用线程安全的日志记录方法。

性能调优max_workers的值可能需要根据您的具体需求和服务器的性能进行调整。过多的线程可能会导致服务器拒绝连接,而过少的线程可能会导致资源未充分利用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rocket 如何解决消息堆积问题、如何消息丢失问题、r安全问题(设置密码)、时间复杂度。

20240803 一、 如何解决消息堆积问题&#xff1f;一般认为单条队列消息差值>10w时 算堆积问题生产太快了线程数量的设置挤压问题 消费者消费出现问题如果堆积的消息不想要了&#xff0c;可以直接跳过堆积 二、 信息丢失问题为什么会丢失解决思路1 记录下来解决思路2 使用roc…

BulingBuling - 活法自如 [Reset Your Routine] - 2

2. What matters most to you? 学习如何优先考虑适合自己的日常工作。 Learn how to prioritize what fits into your routine. Get to your why (找到原因) 因此&#xff0c;当你开始制定新的个性化日常计划时&#xff0c;其中一个关键因素就是要深入挖掘什么对你来说才是真…

Kubernets(k8s) 网络原理一:Pod与宿主机通信

对于刚接触K8S的同学来说&#xff0c;K8S网络显得尤为复杂&#xff0c;例如Pod如何访问主机以及pod间如何进行通信等。本系列文章将站在一个初学者角度&#xff0c;逐层刨析Kubernetes网络实现原理&#xff0c;并利用基本的Linux命令加以实现。 网络虚拟化基石&#xff1a;net…

【Qt】QDial和QSlider

QDial QDial类用于创建一个旋转式的圆形控件&#xff0c;通过鼠标点击旋转、方向键或者pageUp和pageDown调整一个值。常用在需要进行连续调整的场景&#xff0c;比如音量控制、亮度控制、透明度调节等 常见属性 属性说明value持有的值minimum持有值所能到达的最小值maximum持有…

Fiddler抓包及设置

1、打开Fiddler.exe 2、设置过滤&#xff0c;只抓取具体网页或APP 3、勾选 Request Headers 中的 Hide if url contains 过滤项&#xff0c;贴入下方正则表达式&#xff1a;REGEX:(?index)/[^\?/]*\.(css|ico|jpg|png|gif|bmp|wav|js|jpeg|webp)(\?.*)?$&#xff0c;表示过…

云计算 docker 管理镜像和容器

docker的概述 命令说明docker version查看服务器与客户端版本docker info查看 docker 服务配置信息 容器安装部署dnf install -y docker-ce systemctl enable --now docker 配置镜像仓库 镜像概述 镜像管理命令 镜像管理命令说明docker images查看本机镜像docker pull 镜像名…

HDU1100——Trees Made to Order以及卡特兰数

HDU1100——Trees Made to Order 题目描述 Problem - 1100 运行代码 #include <iostream> #include <vector> using namespace std; vector<long long> C(21, 1); // 第21个卡特兰数达到65亿 // 预处理卡特兰数 void Catalan() {for (int i 1; i < 2…

网络学习:应用层DNS域名解析协议

目录 一、简介 二、工作流程 一、简介 DNS( Domain Name System)是“域名系统”的英文缩写&#xff0c;是一种组织成域层次结构的计算机和网络服务命名系统&#xff0c;它用于TCP/IP网络&#xff0c;它所提供的服务是用来将主机名和域名转换为IP地址的工作。 同时,DNS…

[Leetcode 875][Medium]-爱吃香蕉的珂珂-二分搜索

目录 一、题目描述 二 、整体思路 三 、代码 一、题目描述 原题地址 二 、整体思路 题目要求在时间h内(含h)&#xff0c;求解最小速度k。那么首先要知道速度与吃香蕉所用时间的关系。 假设速度为k&#xff0c;那么吃香蕉所用时间t就等于每堆香蕉piles[i]除以速度k所得的向…

电子元器件—电容和电感(一篇文章搞懂电路中的电容和电感)(笔记)(面试考试必备知识点)电容和电感作用、用途、使用、注意事项、特点等(面试必备)-笔记(详解)

作者&#xff1a;Whappy 座右铭&#xff1a;不曾拥有&#xff0c;何来失去&#xff01; 时间&#xff1a;2024年8月2日08:40:04 一、电容的作用 储能&#xff1a; 电容器通过充电储存电荷在电容板上&#xff0c;形成电场储存电能。当需要释放储存的电能时&#xff0c;电荷…

django集成pytest进行自动化单元测试实战

文章目录 一、引入pytest相关的包二、配置pytest1、将django的配置区分测试环境、开发环境和生产环境2、配置pytest 三、编写测试用例1、业务测试2、接口测试 四、进行测试 在Django项目中集成Pytest进行单元测试可以提高测试的灵活性和效率&#xff0c;相比于Django自带的测试…

回测本身就是一种过度拟合?

这也许是一个絮絮叨叨的专题&#xff0c;跟大伙儿唠一唠量化相关的小问题&#xff0c;有感而发写到哪算哪&#xff0c;这是第一期&#xff0c;先唠个10块钱的~ 前段时间在某乎上看到这样一个问题『您怎么理解回测本身就是一种过度拟合&#xff1f;』 个人看来&#xff0c;回测本…

JavaWeb学习——mybatis

目录 一、入门学习 1、什么是mybatis&#xff1f; 2、入门使用 3、配置SQL提示 4、数据库连接池 5、lombok 二、基础操作学习 1、删除 2、新增 3、更新 4、查询 三、XML配置文件 1、映射规范 2、示例代码展示 四、动态SQL 1、学习 2、学习 3、学习 4、学习 一…

TCP/IP协议:互联网通信的基础

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【深度学习】【框架】【基本结构】激活函数

1. relu 2. softmax 3. sigmoid 4. silu 函数&#xff1a;f(x) x * sigmoid(x) 优点&#xff1a; 它既有 ReLU&#xff08;Rectified Linear Unit&#xff09;激活函数的一些优点&#xff08;例如&#xff0c;能够缓解梯度消失问题&#xff09;&#xff0c;又能解决 ReLU …

JavaEE---Spring MVC(2)

5.传递数组 当请求中参数是多个的时候,浏览器就会封装成一个数组 下面是在postman中返回的值 6.传递集合 运行的时候报错了,状态码是500,表示此时是服务器的错误,我们去查看后端源码发现 默认封装的是数组而不是List接口 修改方式: 此时我们就拿到了列表的值 状态码是HT…

文案生成器有哪些?4款为你一键生成原创文案

大家好&#xff01;今天来分享一波超级实用的干货——文案生成器&#xff01;在今天这个信息爆炸的时代&#xff0c;咱们无论是打理社交媒体&#xff0c;还是搞广告宣传等等&#xff0c;对优质文案的需求那是与日俱增。可有时候&#xff0c;灵感枯竭、时间紧迫&#xff0c;怎么…

测试类型分类

前言&#x1f440;~ 上一章我们介绍了如何设计一个测试用例&#xff0c;接下来我们对测试类型进行分类以便更好的了解和分清不同测试测试的内容、对象、时间点等 按照测试对象划分 界面测试&#xff08;也称UI测试&#xff09; 可靠性测试 容错性测试 文档测试 兼容性测…

vue2怎么上传文件夹,并展示文件夹内的图片?

我使用的是element-ui组件库,发现el-upload组件并不能满足需求,于是用原生实现一下,这里贴一下关键代码,如果大家有更好的实现方法,欢迎分享!! 实现效果:

Jangow-1.0.1靶机

一、安装Jangow: 1.0.1靶机 下载靶机&#xff0c;导入到virtualBox里面 开机可以看到&#xff0c;他已经给出了靶机的IP地址&#xff0c;就不用我们自己去探测了 二、信息收集 扫描靶机的端口 首先访问80端口 扫描目录也就是一个site 点击site&#xff0c;来到以下界面 发现…