1

常见的一段代码:

# -*- coding: cp1252 -*-
import csv
import urllib2
import sys
import time
from bs4 import BeautifulSoup
from itertools import islice

page = urllib2.urlopen('http://www.vodafone.de/privat/tarife/red-smartphone-tarife.html').read()
soup = BeautifulSoup(page)
prices = soup.findAll('div', {"class": "price"})

在此之后,我尝试使用以下代码来获取数据:代码 1:

for price in prices:
    print unicode(price.string).encode('utf8')

输出 1:无输出,代码运行没有任何错误并且什么也不打印。

代码 2:

for price in prices:
    textcontent3= u' '.join(price.stripped_strings)
    if textcontent3:
        print textcontent3

输出2:再次无输出,与输出1相同。

代码 3:

for price in prices:
    fonttag = price.find('div')
    if fonttag is not None:
        print unicode(fonttag.string).encode('utf8').strip()

输出 3:无输出,与输出 1 相同

在此之后,我尝试打印 html 的相关部分:

代码 4:

print prices

输出4:

</span></div>, <div class="price">
<span id="price"><br/>
</span></div>, <div class="price">
<span id="price"><br/>
</span></div>]

从 Output4 中可以看出,html 漂亮的汤正在为我刮来没有价格价值。在网页上,此 html 结构如下所示:

<div class="price"><span id="price">49,90 €&lt;/span><br>einmalig</div>

漂亮的汤没有提取 html 页面中提到的价格值,因此我无法抓取价格数据。请帮助我解决这个问题并原谅我的无知,因为我是编程新手。

4

1 回答 1

1

该页面使用大型 JavaScript 结构来加载价格。您可以仅加载该结构:

scripts = soup.find_all('script')
script = next(s.text for s in scripts if s.string and 'window.rates' in s.string)
datastring = script.split('phones=')[1].split(';window.')[0]

这会产生一个庞大的 JavaScript 结构,从以下内容开始:

{sku844082:{name:"Samsung Galaxy SII",image:"/images/m677391_300468.jpg",deliveryTime:"Vorauss. verf&#252;gbar ab Anfang Januar",sku1444291:{p:"prod954312",e:"19.90"},sku1444286:{p:"prod954312",e:"19.90"},sku1444283:{p:"prod954312",e:"39.90"},sku1444275:{p:"prod954312",e:"59.90"},sku1104261:{p:"prod954312",e:"99.90"}},sku894279:{name:"BlackBerry Torch 9810",image:"/images/m727477_300464.jpg",deliveryTime:"Lieferbar innerhalb 48 Stunden",sku1444275:{p:"prod1004495",e:"179.90"},sku1104261:{p:"prod1004495",e:"259.90"},sku1444291:{p:"prod1004495",e:"29.90"},sku1444286:{p:"prod1004495",e:"29.90"},sku1444283:{p:"prod1004495",e:"49.90"}},sku864221:{name:"BlackBerry Bold 9900",image:"/images/m707491_300465.jpg",deliveryTime:"Lieferbar innerhalb 48 Stunden",sku1444275:{p:"prod974431",e:"129.90"},sku1104261:{p:"prod974431",e:"169.90"},sku1444291:{p:"prod974431",e:"49.90"},sku1444286:{p:"prod974431",e:"49.90"},sku1444283:{p:"prod974431",e:"89.90"}}

json不幸的是,这不能直接用模块加载。尽管是有效的 JavaScript,但在没有引用键的情况下它不是有效的 JSON。您需要使用正则表达式来进一步清理它,或者p:"someprice"直接从该字符串中获取信息。

幸运的是,结构可以通过少量的正则表达式魔法来修复:

import re
import json

datastring = re.sub(ur'([{,])([a-z]\w*):', ur'\1"\2":', datastring)
data = json.loads(datastring)

这为您提供了一个大字典,其中包含 SKU 键和带有嵌套字典的字典作为数据,包括带有p产品代码和e价格的嵌套 SKU:

>>> from pprint import pprint
>>> pprint(data['sku864221'])
{u'deliveryTime': u'Lieferbar innerhalb 48 Stunden',
 u'image': u'/images/m707491_300465.jpg',
 u'name': u'BlackBerry Bold 9900',
 u'sku1104261': {u'e': u'169.90', u'p': u'prod974431'},
 u'sku1444275': {u'e': u'129.90', u'p': u'prod974431'},
 u'sku1444283': {u'e': u'89.90', u'p': u'prod974431'},
 u'sku1444286': {u'e': u'49.90', u'p': u'prod974431'},
 u'sku1444291': {u'e': u'49.90', u'p': u'prod974431'}}
于 2013-01-02T12:44:54.060 回答