Python BeautifulSoup有时会给出例外情况

Python BeautifulSoup有时会给出例外情况,python,web-scraping,beautifulsoup,html-parsing,web-crawler,Python,Web Scraping,Beautifulsoup,Html Parsing,Web Crawler,奇怪的是,有时BeautifulSoup对象确实提供了所需的数据,但有时我会得到一个错误,如orlistindex error或超出范围或非类型对象没有属性findNext(),这是嵌套在其他元素中的数据 代码如下: url = 'http://www.computerstore.nl/product/470130/category-208983/asrock-z97-extreme6.html' source_code = requests.get(url) plain_text = sour

奇怪的是,有时BeautifulSoup对象确实提供了所需的数据,但有时我会得到一个错误,如or
listindex error
超出范围
非类型对象没有属性findNext()
,这是嵌套在其他元素中的数据

代码如下:

url = 'http://www.computerstore.nl/product/470130/category-208983/asrock-z97-extreme6.html'
source_code = requests.get(url)
plain_text = source_code.text
soup = BeautifulSoup(plain_text)

a = soup.find(text=('Socket')).find_next('dd').string

print(a)

这意味着存储返回的数据不包含出于某种原因而查找的元素

在代码中添加一些适当的错误处理,捕获异常并在输入中断时转储输入。这样,您就可以查看下载的内容并改进代码

第一步是:

try:
    a = soup.find(text=('Socket')).find_next('dd').string

    print(a)
except:
    print(plain_text)
    raise
如果是大量文本,则将其写入文件


将这么多操作串在一行中也是危险的。如果出了问题,你就不知道该怎么办。将其拆分为几行,以便您可以快速查看它是否可以找到
Socket
dd
元素等。

我建议更改您的代码:

url = 'http://www.computerstore.nl/product/470130/category-208983/asrock-z97-extreme6.html'
source_code = requests.get(url)
plain_text = source_code.text
soup = BeautifulSoup(plain_text)

if soup.find(text=('Socket')):
   a = soup.find(text=('Socket')).find_next('dd').string
else:
   # Display some error info, and/or do some error logging
   print "error"

print(a)

实际问题是单元格值并不总是
Socket
有时它被制表符或空格包围。传递一个:

始终打印
1150


解释我使用过的“有时”一词(感谢@ru毯吸烟者在评论中提出的最初建议):

如果打开页面,然后清理cookies并刷新页面,您可能会看到同一页面的两种不同外观:

如您所见,页面上的块排列方式不同。因此,同一页面有两种不同的外观和HTML源代码-您看到的是一种技术:

在营销和商业智能中,A/B测试是A/B的行话 用两种变体A和B进行随机试验,这两种变体是 在对照实验中进行对照和处理。它是一种 具有两个变量的统计假设检验导致 技术术语,双样本假设检验,用于研究领域 统计数字

换句话说,他们正在试验产品页面并收集统计数据,如点击率、销售额等


仅供参考,以下是我目前的工作代码:

import re

from bs4 import BeautifulSoup
import requests

session = requests.Session()
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36'}
session.get('http://www.computerstore.nl', headers=headers)

response = session.get('http://www.computerstore.nl/product/470130/category-208983/asrock-z97-extreme6.html', headers=headers)
soup = BeautifulSoup(response.content)
print(soup.find(text=re.compile('Socket')).find_next('dd').get_text(strip=True))

“防刮网技术”;不,这似乎是AB测试;如果您在浏览器中禁用cookie,并打开几个选项卡,您将在某些浏览器中看到不同的HTML页面:-)我试图通过回显cookie来保持相同的页面布局,但似乎没有一种明显的方式来获取您实际查看的页面,因此您遇到了相同的问题,但这太难看了:-/@地毯吸烟者我已经更新了答案——显然是AB测试。再次感谢您的提示。好的,您对插座的看法是正确的,现在它可以工作了。谢谢您,但我还有另外两个数据“Format Moederbord”和“芯片组”的问题。如果我用你说的代码代替“Socket”Format Moederbord或“Chipset”,那么问题又来了。@user3660293好吧,它对
芯片组的工作方式与对
Socket
的工作方式相同,但
Format Moederbord
-情况不同,下面是你如何找到它(在A和B两种情况下都有效)
print(soup.find(text=re.compile('format moederbord')).find_parent(['td','dt']).find_next(['td','dd']).find_next(['td','dd]).get_text(strip=True))
。你应该只发布完整的答案,而不是关于如何改进代码的评论。这些可以作为对问题的评论或回答…所以,请帮助我提高我的理解。在亚历克斯最初的问题中,我的答案怎么可能或会成为“完整”答案;这与大多数论坛有点不同,在论坛上,只需给出这样有用的提示就可以了。这样做的最大好处是,当你通过互联网搜索或类似的方式(在论坛上,你有时会有一页又一页的垃圾信息需要挖掘)到达这样的页面时,它可以大大减少“噪音”…感谢帮助页面链接。但是,我没有看到任何提到“完整”答案的内容,我仍然对我的答案不完整的原因感到困惑?特别是,考虑到我使用了该人的原始问题并辅以我的解决方案,“你应该改进你的错误处理”似乎更适合作为对我的评论而不是回答。。。
import re

from bs4 import BeautifulSoup
import requests

session = requests.Session()
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36'}
session.get('http://www.computerstore.nl', headers=headers)

response = session.get('http://www.computerstore.nl/product/470130/category-208983/asrock-z97-extreme6.html', headers=headers)
soup = BeautifulSoup(response.content)
print(soup.find(text=re.compile('Socket')).find_next('dd').get_text(strip=True))