Python BeautifulSoup在没有抛出错误的情况下拖网时暂停
我正在制作一个webscraping程序,通过URL列表中的每个URL,打开带有该URL的页面,并从汤中提取一些信息。大多数情况下,它工作正常,但偶尔程序会停止在列表中前进,但不会终止程序、显示警告/异常或显示错误迹象。我的代码被剥离到相关部分,如下所示:Python BeautifulSoup在没有抛出错误的情况下拖网时暂停,python,web-scraping,beautifulsoup,Python,Web Scraping,Beautifulsoup,我正在制作一个webscraping程序,通过URL列表中的每个URL,打开带有该URL的页面,并从汤中提取一些信息。大多数情况下,它工作正常,但偶尔程序会停止在列表中前进,但不会终止程序、显示警告/异常或显示错误迹象。我的代码被剥离到相关部分,如下所示: from urllib.request import Request, urlopen from bs4 import BeautifulSoup as bs # some code... for url in url_list:
from urllib.request import Request, urlopen
from bs4 import BeautifulSoup as bs
# some code...
for url in url_list:
req = Request(url, headers={"User-Agent": "Mozilla/5.0"})
page = urlopen(req)
soup = bs(page, features="html.parser")
# do some stuff with the soup...
当程序暂停时,如果我手动终止它(使用PyCharm),我会得到以下回溯:
File "/Path/to/my/file.py", line 48, in <module>
soup = bs(page, features="html.parser")
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/bs4/__init__.py", line 266, in __init__
markup = markup.read()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 454, in read
return self._readall_chunked()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 564, in _readall_chunked
value.append(self._safe_read(chunk_left))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 610, in _safe_read
chunk = self.fp.read(min(amt, MAXAMOUNT))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py", line 589, in readinto
return self._sock.recv_into(b)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1052, in recv_into
return self.read(nbytes, buffer)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 911, in read
return self._sslobj.read(len, buffer)
KeyboardInterrupt
File”/Path/to/my/File.py“,第48行,在
soup=bs(第页,features=“html.parser”)
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site packages/bs4/_init__.py”,第266行,在_init中__
markup=markup.read()
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第454行,已读
返回self.\u readall\u chunked()
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第564行,分块
value.append(self.\u safe\u read(chunk\u left))
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py”,第610行,以“安全”读取
chunk=self.fp.read(最小(金额,最大金额))
readinto中的文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/socket.py”,第589行
返回自我。将袜子重新放入(b)
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py”,第1052行,在recv_中
返回自读(N字节,缓冲区)
文件“/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py”,第911行,已读
返回self.\u sslobj.read(len,buffer)
键盘中断
以下是我尝试和学到的:
- 添加了一个检查,以确保在制作汤时页面状态始终为200。故障条件从未发生过
- 创建汤后添加了打印语句。暂停后不会触发此打印语句
- URL总是有效的。这一点可以通过以下事实得到证实:程序并不是每次都在同一个URL上暂停,我有一个类似的程序,它使用几乎相同的代码,在不同的URL集上显示相同的行为
- 我已尝试使用调试器一步一步地完成此操作。在我手动检查的大约30次迭代中,问题没有出现,这可能只是巧合
- 当bs4暂停时,页面返回正确的标题。问题似乎与汤的制作无关
什么可能导致这种行为?请向我们展示完整的回溯!首先使用
print(page)
查看出现问题时从服务器获得的信息。我采纳了你的建议,并相应地更新了我的帖子。我也遇到了同样的问题[忽略文件调用,给定注释大小]self.soup=bs(self.response,'html.parser')
markup=markup.read()返回self.\u readall\u chunked()chunk\u left=self.\u get\u chunk\u left()chunk\u left=self.\u read\u下一步\u chunk\u size()line=self.fp.readline(\u MAXLINE+1)返回self.\u sock.recv\u进入(b)返回self.read(n字节,缓冲区)返回self.\u sslobj.read(len,缓冲区)KeyboardInterrupt@B我已经设法克服了这个问题,但我对解决方案不满意。我当前的方法是使用自定义TimeoutError类设置超时,该类将在设置的秒数后停止解析并重试。这仅仅是因为我使用的是Unix系统(即,不是Windows),即使这样,它也不令人满意。我希望你能找到一个更好的解释,如果你这样做了,让我知道!请给我们看完整的回溯!首先使用print(page)
查看出现问题时从服务器获得的信息。我采纳了你的建议,并相应地更新了我的帖子。我也遇到了同样的问题[忽略文件调用,给定注释大小]self.soup=bs(self.response,'html.parser')
markup=markup.read()返回self.\u readall\u chunked()chunk\u left=self.\u get\u chunk\u left()chunk\u left=self.\u read\u下一步\u chunk\u size()line=self.fp.readline(\u MAXLINE+1)返回self.\u sock.recv\u进入(b)返回self.read(n字节,缓冲区)返回self.\u sslobj.read(len,缓冲区)KeyboardInterrupt@B我已经设法克服了这个问题,但我对解决方案不满意。我当前的方法是使用自定义TimeoutError类设置超时,该类将在设置的秒数后停止解析并重试。这仅仅是因为我使用的是Unix系统(即,不是Windows),即使这样,它也不令人满意。我希望你能找到一个更好的解释,如果你这样做了,让我知道!