首页 > 解决方案 > Web 抓取脚本在几个循环后崩溃

问题描述

在过去的几个月里,我一直在学习编码,尽管到目前为止我已经相当成功,但我仍然坚持使用最新的脚本。

刚刚学会了如何从网站上抓取基本的东西,并制作了一个脚本来保存页面中的图像并循环到下一个图像。但是,在几个循环之后,脚本崩溃并返回此错误消息:

2020-06-03 19:41:03,243 -  DEBUG-  #######Res sURL=https://xkcd.com/2277/
2020-06-03 19:41:03,245 -  DEBUG-  Starting new HTTPS connection (1): xkcd.com:443
2020-06-03 19:41:03,781 -  DEBUG-  https://xkcd.com:443 "GET /2276/ HTTP/1.1" 200 2607
Traceback (most recent call last):
  File "C:/Users/ivanx/PycharmProjects/strong passworddetection/xkcd.py", line 15, in <module>
    comicURL = 'https:'+ elms[0].get('src')
IndexError: list index out of range

我不知道出了什么问题,有什么建议吗?

整个脚本如下:

import requests, bs4, logging, os
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s -  %(levelname)s-  %(message)s')

os.makedirs('xkcd', exist_ok=True)

sURL = 'https://xkcd.com/'

logging.debug('Start of the while loop')
while not sURL.endswith('#'):
site = requests.get(sURL)
soup = bs4.BeautifulSoup(site.text, 'html.parser')
elms = soup.select('#comic > img')

comicURL = 'https:'+ elms[0].get('src')

res = requests.get(comicURL)
res.raise_for_status()

imgFile = open(os.path.join('xkcd', os.path.basename(comicURL)), 'wb')

for chunk in res.iter_content(100000):
    imgFile.write(chunk)
imgFile.close()

logging.debug('#######Res sURL=' + str(sURL))
nElms = soup.select('#middleContainer > ul:nth-child(4) > li:nth-child(2) > a')
pURL = 'https://xkcd.com'+nElms[0].get('href')
sURL = pURL

另外,如果我尝试在图像 2276 上启动循环,我忘了添加,如下所示:

sURL = 'https://xkcd.com/2276'

我收到此错误:

2020-06-03 19:53:26,245 -  DEBUG-  Start of the while loop
2020-06-03 19:53:26,248 -  DEBUG-  Starting new HTTPS connection (1): xkcd.com:443
2020-06-03 19:53:26,766 -  DEBUG-  https://xkcd.com:443 "GET /2276 HTTP/1.1" 301 178
2020-06-03 19:53:26,790 -  DEBUG-  https://xkcd.com:443 "GET /2276/ HTTP/1.1" 200 2607
Traceback (most recent call last):
  File "C:/Users/ivanx/PycharmProjects/strong passworddetection/xkcd.py", line 15, in <module>
    comicURL = 'https:'+ elms[0].get('src')
IndexError: list index out of range

标签: pythonparsingweb-scrapingbeautifulsoup

解决方案


你得到这个是因为你对选择器的调用返回了一个 0 元素列表。

在页面https://xkcd.com/2276上,您可以看到“comic” div 如下所示:

<div id="comic">
<a href="https://twitter.com/kakape/status/1235319133585248259"><img src="//imgs.xkcd.com/comics/self_isolate.png" title="Turns out I&#39;ve been &quot;practicing social distancing&quot; for years without even realizing it was a thing!" alt="Self-Isolate" srcset="//imgs.xkcd.com/comics/self_isolate_2x.png 2x"/></a>
</div>

因为 img 被包裹在一个锚标签中,所以整个东西是孩子,而不是图像。

要为此结构选择图像元素,请使用此选择器:

elms = soup.select('#comic img')

这将选择漫画 div 中包含的任何 img。


推荐阅读