【问题标题】:getting data from HTML code using loop使用循环从 HTML 代码中获取数据
【发布时间】:2018-04-06 11:31:34
【问题描述】:

我正在尝试从一个简单的网站上抓取数据,并使用带有 selenium 的 python 2.7 将其保存到 CSV 文件中,但我遇到了一个小问题。

正如您在下面的 HTML 中看到的,有 2 个类 companyperson。在company 类下有时有 3 个人员类,有时只有 1 或 4 个,因此这意味着没有序列。

每次我只能得到指定公司类下的persons时我应该怎么做?

<tr class="company">..</tr>
<tr class="person">..</tr>
<tr class="person">..</tr>
<tr class="person">..</tr>
<tr class="company">..</tr>
<tr class="person">..</tr>
<tr class="company">..</tr>
<tr class="person">..</tr>
<tr class="person">..</tr>
<tr class="company">..</tr>

数据应该像这样保存在 csv 中:

company1       person1
company1       person2 
company1       person3 

company2       person1 

company3       person1 
company3       person2 

有人帮帮我吗?我应该在这里使用哪种循环?什么是逻辑?

【问题讨论】:

    标签: python html selenium web-scraping automation


    【解决方案1】:

    要仅获取 tr 标记内 class= 'company' 的人员,您必须使用仅选择该 Webelements 的定位器,例如以下一个:

    persons = driver.find_elements_by_xpath('//tr[@class="company"]')
    for person in persons:
        print (person.text)
    

    这是一个如何打印人物的示例,您可以将它们保存在 csv 文件中。

    【讨论】:

    • 那家公司的人呢?实际上我也想要指定公司类别下的人
    【解决方案2】:

    我知道您正在尝试使用 selenium 来实现这一目标。但更有效的是使用requestsbeautifulsoup 库。它们适用于 2.7 和 3.x 版本的 Python。

    您的问题的简单示例:

    好的,html 看起来像这样:

    <tr class="company"></tr>
    <tr class="person">..</tr>
    <tr class="person">..</tr>
    <tr class="person">..</tr>
    <tr class="company"></tr>
    <tr class="person">..</tr>
    <tr class="company"></tr>
    <tr class="person">..</tr>
    <tr class="person">..</tr>
    <tr class="company">..</tr>
    

    我之前的代码:

    import requests
    from bs4 import BeautifulSoup
    
    response = requests.get(yourUrl)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    companyPersons = {}
    for company in soup.find_all('tr',{'class': 'company'}): # find all class'es with company
        for person in company.children: # finds all children tags, e.g. company has 2 childrens person1 and person2, so it will find both
            if company in companyPersons:
                companyPersons[company].append(person)
            else:
                companyPersons[company] = person
    

    编辑到上一个答案 我已经检查了 html 以及需要得到什么。嗯,方法和我之前写的很相似,只是稍作调整。

    test_dict = {}
    for company in soup.find_all('tr', {'class': 'regroworg'}):
        for child in company.find_all('span', {'class': 'regorgname'}):
            for person in company.find_next_siblings('tr', {'class': 'regrow'} != {'class': 'regroworg'}):
                if person['class'] != company['class']:
                    if child.text not in test_dict:
                        test_dict[child.text] = [person.text]
                    else:
                        test_dict[child.text].append(person.text)
                else:
                    break
    

    上面的代码就像你写的那样工作。它应该抓住所有公司的人。代码{'class': 'regrow'} != {'class': 'regroworg'} 中的这一部分正在为找到所需的兄弟姐妹做所有的魔法。 结果将与此类似:

    test_dict['ABB Secheron Ltd.']
    ['\nMr. Emmanuel Mittay, Key Account Manager\nemmanuel.mittay@ch.abb.com\n41 58 586 25 09\n41 58 586 22 28']
    

    现在您可以将数据写入 .CSV 或其他任何位置。

    解决当前问题的代码存在一些问题

    当然我认为从性能角度来看它可以做得更好,但对于当前的问题应该没问题。我注意到大约有 607 家公司(但我不是 100% 确定这个数字),但我的代码提取了 396 个字典键(例如,那是公司的)。所以我建议调试代码并修复它。但我认为代码至少解决了你 50% 的问题,现在只需修复它,让你自己 100% 解决它(我认为这很容易解决)。 ;)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-24
    • 2011-07-14
    • 2019-11-22
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多