• python:循环请求多个url导致链接超时的解决方案


    项目场景:

    在循环中单线程请求多个url导致请求超时 例如:
    这是一个网站里面的20个子页面,我需要从每个子页面里面拿目标数据,第一个想到的就是for循环

       import requests
    
    for i in range(2, 20):
        url_resp_list = requests.get(f"http://www.hnuit.edu.cn/p1/mtsj_{i}.html")
        print(url_resp_list)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题描述

    TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
    在这里插入图片描述


    原因分析:

    **- 但是像这种一个循环里不停的访问url,会让http链接一直存在导致占用过多(从百度查的一个原因之一)出现连接超时的情况

    • 1.ip被封。(能请求就说明ip没被封)
      2.http的连接数超过最大限制。headers的Connection参数默认为keep-alive,导致之前所有的链接都一直存在,占用了后续的链接请求。
      3.网站服务器太差,爬取请求的速度太快。(它急着响应,而网站的服务器不给力,就直接断掉了)

    • 我可能就是访问的这个网站服务器太差了跟不上爬虫的速度响应太慢(可能),因为我访问豆瓣所有子页面时也用的是for循环,他没有出现这种问题**


    解决方案:

    **这是在百度上找到的方案,对于我的这个问题好像没什么用,只是增加了几个访问的url链接而已,还是满足不了需求

    • 1.换ip,更换headers或者使用代理ip。
      2.将Connection参数的值改为close。或者在requests.get前一行添加requests.adapters.DEFAULT_RETRIES = 5,意思是连接失败时重连五次。
      3.因为单线程请求过多url(单线程请求的url很一直占用)导致http的链接数量超过了最大限制(也可能是对方服务器不好)
      那么用多线程来解决就很好,多开几个线程,那么每个线程请求的url数量就会减少,很大程度上降低压力
      这是原文链接:
      https://blog.csdn.net/qq_43814415/article/details/112907350

    第二种方案就是自己试出来的,因为刚好学到了多线程,我想单线程压力大,那就把工作量大的任务多开几个线程,结果真的可以,速度比for循环更快,把一个工作单元封装为一个任务,丢到线程池里(资源足够的情况下)在线程池里加个循环,把所有任务都提交到池里,让这些线程去完成**

    from concurrent.futures import ThreadPoolExecutor
    import requests
    
    
    def get_data(i):
        url_resp_list = requests.get(f"http://www.hnuit.edu.cn/p1/mtsj_{i}.html")
        print(url_resp_list)
        print(f"线程{i}")
    
    
    with ThreadPoolExecutor(50) as t2:  # 开50个线程去完成这20个任务,也可以开15个,按照理想状态来说每个线程只需要一次url请求就可以了
        for i in range(2, 20):
            t2.submit(get_data, i)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    通过截图就可以看到是很多个线程一起在跑,如果是单线程的话应该是有顺序的打印
    总的来说就是把一个重复的操作抽象出来封装程一个任务,通过循环把所有任务都提交到线程池里
    最重要的一点就是他不会像单线程一样,要是有一个链接无法响应,就会一直卡在那里,
    而多线程不同,不会因为某个链接无法响应就无法运行,最多就是负责那个页面的线程拿不到数据而已

  • 相关阅读:
    [洛谷] P1143 进制转换
    Python二级 每周练习题27
    gateway网关转发请求到nacos不同namespace和不同group下服务实例源码改造
    0037__一文了解嵌入式系统中常用外围接口
    这些Git事故灾难, 你经历过几个?
    软件工程和计算机科学与技术学习方向区别
    Python学习:类与实例
    推荐模型之多任务模型:ESMM、MMOE
    QCustomPlot(2)-QCPGraph
    双指针--反转字符串,数组拆分,两数之和,移除元素,最大连续1的个数,长度最小子数组
  • 原文地址:https://blog.csdn.net/weixin_51753483/article/details/126148071