在一个多的findAll for循环

问题描述 投票:1回答:2

我使用BeatufulSoap来读取网页的一些数据。此代码工作正常,但我想改善它。

如何让我的for循环中提取超过一件每次迭代的数据?在这里,我有3个for循环,从得到的值:

for elem in bsObj.findAll('div', class_="grad"): ...
for elem in bsObj.findAll('div', class_="ulica"): ...
for elem in bsObj.findAll('div', class_="kada"): ...

如何改变这种在一个for回路工作?当然,我想一个简单的解决方案。输出可以列表

到目前为止我的代码

from bs4 import BeautifulSoup

# get data from a web page into the ``html`` varaible here

bsObj = BeautifulSoup(html.read(),'lxml')

mj=[]
adr=[]
vri=[]

for mjesto in bsObj.findAll('div', class_="grad"):
    print (mjesto.get_text())
    mj.append(mjesto.get_text())


for adresa in bsObj.findAll('div', class_="ulica"):
    print (adresa.get_text())
    adr.append(adresa.get_text())


for vrijeme in bsObj.findAll('div', class_="kada"):
    print (vrijeme.get_text())
    vri.append(vrijeme.get_text())
python python-3.x web-scraping beautifulsoup
2个回答
1
投票

您可以使用BeautifulSoup的select方式来指定您各种所需的元素,做任何你想要他们。在这种情况下,我们会使用:is()伪类简化CSS选择器模式,但基本上我们正在寻找有一流的divgrad,或ulica任何kada。当返回的每个元素匹配模式,我们只是对它们进行排序由哪个阶级它们对应于:

from urllib.request import urlopen
from bs4 import BeautifulSoup
import requests

lokacija="http://www.hep.hr/ods/bez-struje/19?dp=koprivnica&el=124"
datum="12.02.2019"
lokacija=lokacija+"&datum="+datum
print(lokacija)
r = requests.get(lokacija)
print(type(str(r)))
print(r.status_code)

html = urlopen(lokacija)

bsObj = BeautifulSoup(html.read(),'lxml')

print("Datum radova:",datum)
print("HEP područje:",bsObj.h3.get_text())

mj=[]
adr=[]
vri=[]
hep_podrucje=bsObj.h3.get_text()

for el in bsObj.select('div:is(.grad, .ulica, .kada)'):
    if 'grad' in el.get('class'):
        print (el.get_text())
        mj.append(el.get_text())
    elif 'ulica' in el.get('class'):
        print(el.get_text())
        adr.append(el.get_text())
    elif 'kada' in el.get('class'):
        print (el.get_text())
        vri.append(el.get_text())

0
投票

注:基本解释提前。如果你知道这一点,直接跳到可能性上市

要更改代码进入一个循环,你看那个保持不变的部分和不同的部分。在你的情况,你会发现一个div,获取文本,并将其添加到列表中。

class对象的div属性的每个时间不同,所以做你添加到列表中。甲for循环的工作原理是具有被赋予不同的值每一次迭代一个变量,然后executig内的代码。

我们得到的基本结构:

for div_class in <div classes>:
    <stuff to do>

现在,在<stuff to do>,我们有一个不同的列表中的每个时间。我们需要得到一个不同的列表进入循环的一些方法。对于这一点,有多种可能性:

  • 把列表转换为dict和使用项目查找
  • zip名单与<div classes>并在它们之间迭代

前两个会涉及使用嵌套的循环,结果找类似这样的:

list_1 = []
list_2 = []
list_3 = []
for div_class, the_list in zip(['div_cls1', 'div_cls2', 'div_cls3'], [list_1, list_2, list_3]):
    for elem in bsObj.find_all('div', class_=div_class):
        the_list.append(elem.get_text())

要么

lists = {'div_cls1': [], 'div_cls2': [], 'div_cls3': []}
for div_class in lists:  # note: keys MUST match the class of div elements
    for elem in bsObj.find_all('div', class_=div_class):
        lists[div_class].append(elem.get_text)

当然,内环可以通过列表理解来代替(工程为dict方法):lists[div_class] = [elem.get_text() for elem in bsObj.find_all('div', class_=div_class)]

© www.soinside.com 2019 - 2024. All rights reserved.