Я пытаюсь получить контактную информацию со страницы. Мне нужно имя, должность, телефон и адрес электронной почты.

Я изучаю Python и пытаюсь написать код для данных, которые я знаю. Мне удалось вытащить блоки div с отдельными контактами, но я не уверен, как пролистать их, когда они у меня есть.

tags = soup.find_all('div', attrs={'class':'tshowcase-inner-box'})

Но потом я хотел ползти через детей и не имел успеха.

    fullname = soup.find('div', attrs={'class':'tshowcase-box-title'})
    title = soup('div', attrs={'class':'tshowcase-single-position'})
    phone = soup('div', attrs={'class':'tshowcase-single-telephone'})
    email = soup('div', attrs={'class':'tshowcase-box-social'})

Я не уверен, что дальше, хотя и ценю любые указатели.

Вот пример HTML:

<div class="tshowcase-inner-box ts-float-left ">
    <div class="tshowcase-box-info ts-align-left  ">
        <div class="tshowcase-box-title">FULL NAME</div>
        <div class="tshowcase-box-details">
            <div class="tshowcase-single-position"><i class="fa fa-chevron-circle-right"></i>JOB TITLE</div>
            <div class="tshowcase-single-telephone"><i class="fa fa-phone-square"></i><a href="tel:PHONE">PHONE</a></div>
        </div>
        <div class="tshowcase-box-social"><a href="mailto:EMAIL" rel="nofollow" target="_blank"><i class="fa fa-envelope-o fa-lg"></i></a></div>
    </div>
</div>
1
Nicole C. Baratta 7 Июл 2019 в 02:36

3 ответа

Лучший ответ

Если вы проведете цикл по каждому списку, вы можете проверить его наличие и действовать соответственно

from bs4 import BeautifulSoup as bs
import requests

html = '''
<div class="tshowcase-inner-box ts-float-left ">
    <div class="tshowcase-box-info ts-align-left  ">
        <div class="tshowcase-box-title">FULL NAME</div>
        <div class="tshowcase-box-details">
            <div class="tshowcase-single-position"><i class="fa fa-chevron-circle-right"></i>JOB TITLE</div>
            <div class="tshowcase-single-telephone"><i class="fa fa-phone-square"></i><a href="tel:PHONE">PHONE</a></div>
        </div>
        <div class="tshowcase-box-social"><a href="mailto:EMAIL" rel="nofollow" target="_blank"><i class="fa fa-envelope-o fa-lg"></i></a></div>
    </div>
</div>
<div class="tshowcase-inner-box ts-float-left ">
    <div class="tshowcase-box-info ts-align-left  ">
        <div class="tshowcase-box-title">FULL NAME2</div>
        <div class="tshowcase-box-details">
            <div class="tshowcase-single-position"><i class="fa fa-chevron-circle-right"></i>JOB TITLE2</div>
            <div class="tshowcase-single-telephone"><i class="fa fa-phone-square"></i><a href="tel:PHONE">PHONE2</a></div>
        </div>
        <div class="tshowcase-box-social"><a href="mailto:EMAIL2" rel="nofollow" target="_blank"><i class="fa fa-envelope-o fa-lg"></i></a></div>
    </div>
</div>
'''
soup = bs(html, 'lxml')
results = []

for listing in soup.select('.tshowcase-inner-box'):
    name = listing.select_one('.tshowcase-box-title')
    job = listing.select_one('.tshowcase-single-position')
    tel = listing.select_one('.tshowcase-single-telephone')
    email = listing.select_one('[href^=mailto]')
    if name is None:
        name = 'Not present'
    else:
        name = name.text
    if job is None:
        job = 'Not present'
    else:
        job = job.text
    if tel is None:
        tel = 'Not present'
    else:
        tel = tel.text
    if email is None:
        email = 'Not present'
    else:
        email = email['href'].replace('mailto:','')
    results.append({ 'name' : name, 'job' : job, 'tel': tel, 'email': email })
print(results)
0
QHarr 7 Июл 2019 в 05:14

Вы можете использовать soup.find_all, чтобы найти элементы, а затем получить доступ к значениям text и href:

from bs4 import BeautifulSoup as soup
import re
d = soup(html, 'html.parser')
s = [i.text for i in d.find_all('div', {'class':re.compile('title$|position$|telephone$')})]
result = [*s, d.find('div', {'class':'tshowcase-box-social'}).a['href'][7:]]

Выход:

['FULL NAME', 'JOB TITLE', 'PHONE', 'EMAIL']

Если вы пытаетесь очистить несколько контактных блоков на странице, вы можете преобразовать приведенный выше код в функцию, которая принимает объект bs4 для очистки одного списка и повторения всех блоков div:

def get_contact(d):
   s = [i.text for i in d.find_all('div', {'class':re.compile('title$|position$|telephone$')})]
   return [*s, d.find('div', {'class':'tshowcase-box-social'}).a['href'][7:]]

results = [get_contact(i) for i in soup(html, 'html.parser').find_all('div', {'class':'tshowcase-inner-box'})]

Выход:

[['FULL NAME', 'JOB TITLE', 'PHONE', 'EMAIL']]
0
Ajax1234 6 Июл 2019 в 23:43

Моя версия получения контактной информации:

data = '''<div class="tshowcase-inner-box ts-float-left ">
    <div class="tshowcase-box-info ts-align-left  ">
        <div class="tshowcase-box-title">FULL NAME</div>
        <div class="tshowcase-box-details">
            <div class="tshowcase-single-position"><i class="fa fa-chevron-circle-right"></i>JOB TITLE</div>
            <div class="tshowcase-single-telephone"><i class="fa fa-phone-square"></i><a href="tel:PHONE">PHONE</a></div>
        </div>
        <div class="tshowcase-box-social"><a href="mailto:EMAIL" rel="nofollow" target="_blank"><i class="fa fa-envelope-o fa-lg"></i></a></div>
    </div>
</div>'''

from bs4 import BeautifulSoup

soup = BeautifulSoup(data, 'lxml')

data = []
for div in soup.select('.tshowcase-inner-box'):
    data.append([])
    data[-1].extend(txt.strip() for txt in div.get_text(separator='|').split('|') if txt.strip())
    data[-1].extend(a['href'].replace('mailto:', '') for a in div.select('a[href*="mailto:"]'))

print(data)

Печать :

[['FULL NAME', 'JOB TITLE', 'PHONE', 'EMAIL']]
0
Andrej Kesely 7 Июл 2019 в 04:40