BeautifulSoup多次使用选择

时间:2017-12-19 15:21:33

标签: python python-3.x beautifulsoup

我的问题与此answer有关。

我有以下代码:

import urllib.request
from bs4 import BeautifulSoup

time = 0

html = urllib.request.urlopen("https://www.kramerav.com/de/Product/VM-2N").read()
html2 = urllib.request.urlopen("https://www.kramerav.com/de/Product/SDIA-IN2-F16").read()
try:
    div = str(BeautifulSoup(html).select("div.large-image")[0])
    if(str(BeautifulSoup(html).select("div.large-image")[1]) != ""):
        div += str(BeautifulSoup(html).select("div.large-image")[1])
    time = time + 1
except IndexError:
    div = ""
    time = time + 1
finally:
    print(str(time) + div)

变量html的网站有2个名为“large-image”的div-classes。变量html2的站点只有1。 使用html,程序按预期工作。但是,如果我切换到html2,变量div将完全为空。

我想保存1 div-class而不是保存任何东西。我怎么能这样做呢?

2 个答案:

答案 0 :(得分:1)

  

变量div将完全为空。

那是因为你的错误处理程序为它分配了空字符串。

请不要以这种方式使用下标,条件和处理程序。使用for迭代select()的结果,构建结果列表(或字符串)会更自然。

此外,您应该只创建一次soup = BeautifulSoup(html),因为这可能是一项相当昂贵的操作,因为它会仔细分析可能很长的网页。有了它,您可以使用以下内容构建HTML片段列表:

    images = [image
              for image in soup.select('div.large-image')]

或者,如果由于某种原因你不喜欢列表理解,你可以等同地写:

    images = []
    for image in soup.select('div.large-image'):
        images.append(image)

然后使用div = '\n'.join(images)获取所需的html。

答案 1 :(得分:0)

您可以连接for循环

中的所有项目
    all_divs = soup.select("div.large-image")

    for item in all_divs:
        div += str(item)
        time += 1

或使用join()

    time = len(all_divs)

    div = ''.join(str(item) for item in all_divs)

您也可以直接在for循环内写入文件,然后进入行

    for item in all_divs:
        csv_writer.writerow( [str(item).strip()] )
        time += 1

工作示例

import urllib.request
from bs4 import BeautifulSoup
import csv

div = ""
time = 0

f = open('output.csv', 'w')
csv_writer = csv.writer(f)

all_urls = [
  "https://www.kramerav.com/de/Product/VM-2N",
  "https://www.kramerav.com/de/Product/SDIA-IN2-F16",
]

for url in all_urls:
    print('url:', url)

    html = urllib.request.urlopen(url).read()

    try:
        soup = BeautifulSoup(html)
        all_divs = soup.select("div.large-image")

        for item in all_divs:
            div += str(item)
            time += 1

        # or     
        time = len(all_divs)
        div = ''.join(str(item) for item in all_divs)

        # or

        for item in all_divs:
            #div += str(item)
            #time += 1
            csv_writer.writerow( [time, str(item).strip()] )

    except IndexError as ex:
        print('Error:', ex)
        time += 1
    finally:
        print(time, div)

f.close()