【问题标题】:BeautifulSoup filtering data from list elements on html pagesBeautifulSoup 从 html 页面上的列表元素中过滤数据
【发布时间】:2015-11-17 02:59:47
【问题描述】:

我正在尝试从多个 html 页面收集数据,特别是列表元素中的数据。我试图将此数据添加到字典中以供以后使用,我必须按预期提取数据,但我将数据输入到字典中没有按预期工作。我目前正在覆盖每个条目,而不是添加新条目。谁能指出我哪里出错了?

当前代码

from BeautifulSoup import BeautifulSoup
import requests
import re

person_dict = {}

.....
<snip>
<snip>
.....

soup = BeautifulSoup(response.text)

    div = soup.find('div', {'id': 'object-a'})
    ul = div.find('ul', {'id': 'object-a-1'})
    li_a = ul.findAll('a', {'class': 'title'})
    li_p = ul.findAll('p', {'class': 'url word'})
    li_po = ul.findAll('p')

    for a in li_a:
        nametemp = a.text
        name = (nametemp.split(' - ')[0])
        person_dict.update({'Name': name})     #I attempted updating
    for lip in li_p:
        person_dict['url'] = lip.text          #I attempted adding directly

    for email in li_po:   
        reg_emails = re.compile('[a-zA-Z0-9.]*' + '@')        
        person_dict['email'] = reg_emails.findall(email.text)

print person_dict # results in 1 entry being returned

测试数据

<div id="object-a">
    <ul id="object-a-1">
            <li>
              <a href="www.url.com/person" class="title">Person1</a>
              <p class="url word">www.url.com/Person1</p>
              <p>Person 1, some foobar possibly an email@address.com &nbsp;...</p>
            </li>


            <li>
              <a href="www.url.com/person" class="title">Person2</a>
              <p class="url word">www.url.com/Person1</p>
              <p>Person 2, some foobar possibly an email@address.com &nbsp;...</p>
            </li>


            <li>
              <a href="www.url.com/person" class="title">Person3</a>
              <p class="url word">www.url.com/Person1</p>
              <p>Person 3, some foobar, possibly an email@address.com &nbsp;...</p>
            </li>
    </ul>

【问题讨论】:

  • 每次迭代都使用'Name' 键,不是吗?键必须是唯一的。
  • 是的,我想在每次迭代中添加一个新的Name 和相关数据
  • 为什么需要字典,只需将元组附加到列表中,例如List.append((name, email, foo))
  • 我的印象是字典形式会更方便。但我当然对编码很陌生,你能解释一下为什么最好有一个元组列表吗?

标签: python html beautifulsoup


【解决方案1】:

是否需要使用字典取决于您,但如果您选择使用字典,最好为每个列表项使用单独的字典,而不是为所有条目使用单独的字典。

我建议您将所有条目存储在一个列表中。以下代码显示了两个建议,要么使用tuple 来存储每个项目的各种信息位,要么使用字典。

如果您只是打算显示信息或将其写入文件,tuple 解决方案会更快。

# Two possible ways of storing your data: a list of tuples, or a list of dictionaries
entries_tuples = []             
entries_dictionary = []

soup = BeautifulSoup(text)

div = soup.find('div', {'id': 'object-a'})
ul = div.find('ul', {'id': 'object-a-1'})

for li in ul.findAll('li'):
    title = li.find('a', {'class': 'title'})
    url_href = title.get('href')
    person = title.text
    url_word = li.find('p', {'class': 'url word'}).text
    emails = re.findall(r'\s+(\S+@\S+)(?:\s+|\Z)', li.findAll('p')[1].text, re.M)       # allow for multiple emails

    entries_tuples.append((url_href, person, url_word, emails))
    entries_dictionary.append({'url_href' : url_href, 'person' : person, 'url_word' : url_word, 'emails' : emails})

for url_href, person, url_word, emails in entries_tuples:
    print '{:25} {:10} {:25} {}'.format(url_href, person, url_word, emails)

print

for entry in entries_dictionary:
    print '{:25} {:10} {:25} {}'.format(entry['url_href'], entry['person'], entry['url_word'], entry['emails'])

对于您的示例 HTML,将显示以下内容:

www.url.com/person        Person1    www.url.com/Person1       [u'email@address.com']
www.url.com/person        Person2    www.url.com/Person1       [u'email@address.com']
www.url.com/person        Person3    www.url.com/Person1       [u'email@address.com', u'email@address.com']

www.url.com/person        Person1    www.url.com/Person1       [u'email@address.com']
www.url.com/person        Person2    www.url.com/Person1       [u'email@address.com']
www.url.com/person        Person3    www.url.com/Person1       [u'email@address.com', u'email@address.com']

注意,从文本中提取电子邮件地址本身就是一个完整的问题。上述解决方案可以轻松匹配实际上不是格式正确的电子邮件地址的条目,但在这里就足够了。

【讨论】:

  • 好的,我可以看到我的方法有点不对劲,感谢您指出这一点,并感谢您回答我实际提出的问题。我可以看到为什么我的字典没有按预期更新。
【解决方案2】:

你可能会走错路。试试这样的:

from BeautifulSoup import BeautifulSoup
import re

text = open('soup.html') # You are opening the file differently
soup = BeautifulSoup(text)
list_items = soup.findAll('li')

people = []

for item in list_items:
    name = item.find('a', {'class': 'title'}).text
    url = item.find('p', {'class': 'url word'}).text
    email_text = item.findAll('p')[1].text
    match = re.search(r'[\w\.-]+@[\w\.-]+', email_text)
    email = match.group(0)

    person = {'name': name, 'url': url, 'email': email}
    people.append(person)

print people

【讨论】:

  • 感谢您尝试回答我实际提出的问题,我喜欢您在容器中添加一个条目(在本例中为列表)的方法,但是您能否解释一下为什么要添加看起来将字典变成列表?您决定采用这种方法有什么特别的原因吗?
  • 我不知道您在收集数据后会如何使用数据,但通过这种方式您可以迭代列表并在包含分组键、值对的字典中获取数据。跨度>
猜你喜欢
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 2020-04-13
  • 1970-01-01
  • 2014-06-03
  • 2017-10-15
  • 2018-07-14
  • 1970-01-01
相关资源
最近更新 更多