Python网站爬虫程序假死不报错,是哪里设计有问题?

用于网站爬图 代码太多,贴关键部分,应该问题就出自以下爬虫部分:

for i in soup1.find_all("input", type="image"):
	imgnow = time.strftime("%Y%m%d%H%M%S")
	imgurl = i['data-src']
	rname = imgurl .split('/')[-1]
	opener = urllib.request.build_opener()
	opener.addheaders = self.UA
	urllib.request.install_opener(opener)
    try:
      #就是卡这里不动了,没有任何动静,程序静止了
  urllib.request.urlretrieve(
  imgurl, "./Pic/%s" % imgnow + "_" + str(rname))     

   except Exception as e:
	print("出错了:%s,继续..." % e)
        continue


Python网站爬虫程序假死不报错,是哪里设计有问题?

17 回复

需要加入超时处理,免得在对方网站限制或关闭时候有反应


我遇到过这种问题,爬虫假死不报错通常是因为网络请求被阻塞了。最常见的原因是:

  1. 没有设置超时 - 请求卡住后永远等待
  2. 同步请求阻塞 - 一个请求卡住整个程序就停了
  3. 异常处理不完整 - 某些异常被静默处理了

这是修复后的代码示例:

import requests
import concurrent.futures
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def create_session():
    session = requests.Session()
    # 设置重试策略
    retry = Retry(
        total=3,
        backoff_factor=0.5,
        status_forcelist=[500, 502, 503, 504]
    )
    adapter = HTTPAdapter(
        max_retries=retry,
        pool_connections=100,
        pool_maxsize=100
    )
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    return session

def fetch_url(url, timeout=10):
    try:
        session = create_session()
        response = session.get(url, timeout=timeout)
        response.raise_for_status()
        return response.text
    except Exception as e:
        print(f"请求失败 {url}: {e}")
        return None

def main():
    urls = ['http://example.com/page1', 'http://example.com/page2']
    
    # 使用线程池并发请求
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        future_to_url = {executor.submit(fetch_url, url): url for url in urls}
        
        for future in concurrent.futures.as_completed(future_to_url):
            url = future_to_url[future]
            try:
                data = future.result(timeout=15)  # 每个任务单独超时
                if data:
                    print(f"成功获取 {url}")
            except concurrent.futures.TimeoutError:
                print(f"任务超时: {url}")
            except Exception as e:
                print(f"处理失败 {url}: {e}")

if __name__ == "__main__":
    main()

关键改进点:

  • 使用Session对象并配置连接池
  • 设置合理的超时(连接超时和读取超时)
  • 添加重试机制处理临时故障
  • 使用线程池避免单个请求阻塞整个程序
  • 为每个异步任务设置单独的超时控制

如果还假死,考虑用异步库(aiohttp)替代requests。

建议:加上超时和并发控制基本能解决假死问题。

怎么加,求指教

推荐 requests。 当然了 不管用啥 都得考虑超时

加了超时,现在可以抛出异常了,但老是有这种,放在 try 了,10 个请求,有 5 个就是这种,遇到就 pass 了继续。。。。:

[WinError 10054] 远程主机强迫关闭了一个现有的连接。,继续…



要么就干脆直接报错程序 终止了:
requests.exceptions.ConnectionError: (‘Connection aborted.’, ConnectionResetError(10054, ‘远程主机强迫关闭了一个现有的连接。’, None, 10054, None))

ConnectionReset,对端发了 reset。原因很多,网络不好 对方等待超时,对方发现你再爬虫,所以超时。 各种原因。 想要仔细分析原因 抓包分析,看看是网络不好,还是对方主动的。

换了网络,不像是网络问题,总之感觉爬的很费力,各种异常,try 都 try 不住

必须要 ip 代理

python 有个叫做 retry 的库,可以试一下,很方便的。

要加重试机制,任何网络都会不稳定,对方服务器也可能出现故障,屏蔽等情况

好的,我试一下
确实要加重啊,不然跑几分钟就直接崩了

骚年,你得学会 requests。
你说的假死问题应该出在你的代码上,好好排查。

为什么不用 requests ? requests.get(timeout=10)

这个没啥用,只针对链接超时,读取超时得这样写 timeout=(3,6)
不过这样写了也没卵用~

请求地址用的就是 requests,只不过下载图片用的是 urllib.request.urlretrieve

我以前抓携程的时候也遇到这种问题
程序就假死在那了。

后来,我做了一个断点续爬来解决这个问题。

回到顶部