python-3.x - 多线程爬虫运行一段时间后越来越慢

标签 python-3.x tcp python-requests windows-10 python-multithreading

我写了一个Windows下的多线程网络爬虫。我使用的库是 requeststhreading。我发现程序在运行一段时间后(大约500页)变得越来越慢。当我停止程序并再次运行时,程序再次加速。似乎有许多挂起的连接,导致速度变慢。我应该如何解决这个问题?

我的代码:

import requests, threading,queue
req = requests.Session()

urlQueue = queue.Queue()
pageList = []
urlList = [url1,url2,....url500]
[urlQueue.put(i) for i in urlList]

def parse(urlQueue):

    try:
       url = urlQueue.get_nowait()
    except:
       break
    try:
       page = req.get(url)
       pageList.append(page)
    except:
       continue

if __name__ == '__main__':

    threadNum = 4
    threadList = []
    for i in threadNum:
        t = threading.Thread(target=(parse),args=(urlQueue,))
        threadList.append(t)
    for thread in threadList:
        thread.start()
    for thread in threadList:
        thread.join()

我搜索了这个问题。有回答说是linux下TCP的重用和回收问题。我不太明白这个答案。答案如下。我翻译了中文的答案。

  1. 在 Linux shell 中键入命令:netstat -n | awk '/^tcp/{++S[$NF]} END {for(a in S) print a, S[a]}'
  2. 发现 TIME_WAIT 接近 2W。所以,一定有很多 TCP 连接。
  3. 使用以下代码分别设置TCP的重用时间和回收时间: echo "1">/proc/sys/net/ipv4/tcp_tw_reuse, echo "1">/proc/sys/net/ipv4/tcp_tw_recycle

这个答案似乎是正确的。应该是网络问题。 Windows下应该怎么解决。

最佳答案

多线程爬虫将耗尽 TCP 连接。我们需要设置TcpTimedWaitDelay来快速重用和回收TCP连接。我们可以通过手动更改regedit或键入代码来解决问题。

如何在 Windows 上使用代码执行此操作: (您需要以管理员身份运行代码,否则会报错。)

import win32api,win32con

key = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, r'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters', 0, win32con.KEY_SET_VALUE)

win32api.RegSetValueEx(key, 'TcpTimedWaitDelay', 0, win32con.REG_SZ, '30')

win32api.RegCloseKey(key)

如何在 Windows 上手动执行此操作:

  1. 打开RUN,然后输入regedit
  2. 查找:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters
  3. 点击编辑 - 新建 - 可扩展字符串值
  4. 创建TcpTimedWaitDelay(如果该条目已经存在,则不需要创建)
  5. 将值改为30。(TCP取值范围30~300秒,默认120秒,默认太长 多线程爬虫很长。)

感谢你们所有人对问题的贡献。这可以帮助很多人。

Reference site

关于python-3.x - 多线程爬虫运行一段时间后越来越慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53946600/

相关文章:

python - 使用 Pandas 数据框中的值作为另一个数据框中的列名

sockets - Golang tcp socket read 最终给出 EOF

Android,在 sleep 模式下保持TCP连接

c++ - 通过 Modbus TCP 与 CMMO-ST-C5-1-LKP Festo Controller 进行 Qt/C++ 通信

javascript - Python 抓取具有多个嵌套 <!DOCTYPE html> 的站点(具有多个 <!DOCTYPE html> 声明的站点)

python - 如何向 TypedDicts 列表中的每个字典添加键

python - 在 python 中导入具有用户输入名称的模块

python-3.x - 使用 python requests 模块登录网站

python - 如何使用Python加快文件的下载速度?

python - 类型错误 : '>' not supported between instances of 'int' and 'str'