BeautifulSoup有时会例外

时间:2014-12-15 15:30:20

标签: python web-scraping beautifulsoup html-parsing web-crawler

奇怪的是,有时BeautifulSoup对象确实提供了所需的数据,但有时我会收到类似或listindex errorout of rangenonetype object does not have attribute 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)

3 个答案:

答案 0 :(得分:3)

实际问题是,单元格值并非总是Socket有时 被标签或空格包围。不是检查确切的text匹配,而是传递compiled regular expression pattern

import re

soup.find(text=re.compile('Socket')).find_next('dd').get_text(strip=True)

始终打印1150


解释"有时"我已经使用了一句话(感谢@carpetsmoker在评论中提出的初步建议):

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

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

  

在市场营销和商业智能方面,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))

答案 1 :(得分:-1)

这意味着商店返回的数据不包含您出于某种原因寻找的元素。

为捕获异常的代码添加一些正确的错误处理,并在输入中断时将其转储。这样,您就可以看到下载的内容并改进了代码。

第一步是:

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

    print(a)
except:
    print(plain_text)
    raise

如果有很多文字,请将其写入文件。

在一行中串联如此多的操作也很危险。如果出现问题,那么你不会知道什么。将其拆分为多行,以便您可以快速查看是否可以找到Socketdd元素等。

答案 2 :(得分:-1)

我对您的代码进行了建议更改:

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)