Запись извлеченных элементов с веб-сайта на лист .xls со списками разной длины с использованием модуля Pandas в Python

#python #excel #pandas #web-scraping #beautifulsoup

#python #excel #pandas #очистка веб-страниц #beautifulsoup

Вопрос:

Я новичок в программировании на Python и практикуюсь в извлечении различных значений с веб-сайтов. Я извлек элементы с определенного веб-сайта и теперь хочу записать их в файл .xls.

Вся веб-страница содержит 714 записей, включая повторяющиеся записи, но на листе Excel отображается только 707 записей из-за функции zip (), которая останавливается, когда исчерпывается наименьший список. Здесь самый маленький список — это список адресов электронной почты. Таким образом, он исчерпывается, и итерация останавливается из-за свойства функции zip ().Я даже сохранил проверку этого в пределах условия if для записей, у которых нет адреса электронной почты, чтобы отображалось «Нет адреса электронной почты», но все тот же результат отображается с записями 704 с дубликатами. Пожалуйста, скажите, где я ошибаюсь, и, если возможно, предложите, что нужно сделать для удаления повторяющихся записей и отображения «Нет адреса электронной почты» там, где нет электронной почты.

 from bs4 import BeautifulSoup as bs
import pandas as pd

res = requests.get('https://www.raywhite.com/contact/?type=Peopleamp;target=peopleamp;suburb=Sydney, NSW 2000amp;radius=50''amp;firstname=amp;lastname=amp;_so=contact', headers = {'User-agent': 'Super Bot 9000'})
soup = bs(res.content, 'lxml')

names=[]
positions=[]
phone=[]
emails=[]
links=[l1['href'] for l1 in soup.select('.agent-name a')]

nlist = soup.find_all('li', class_='agent-name')
plist= soup.find_all('li',class_='agent-role')
phlist = soup.find_all('li', class_='agent-officenum')
elist = soup.find_all('a',class_='val withicon')

for n1 in nlist:
    names.append(n1.text)
for p1 in plist:
    positions.append(p1.text)
for ph1 in phlist:
    phone.append(ph1.text)
for e1 in elist:
    emails.append(e1.get('href') if e1.get('href') is not None else 'No Email address')


df = pd.DataFrame(list(zip(names,positions,phone,emails,links)),columns=['Names','Position','Phone','Email','Link'])
df.to_excel(r'C:UserslaptopDesktopRayWhite.xls', sheet_name='MyData2', index = False, header=True)

  

Лист Excel выглядит следующим образом, где мы можем видеть название последней записи, и его адрес электронной почты не совпадает:

Ray Белый лист Excel

Ray Белый лист Excel

Ответ №1:

Похоже, что вы выполняете множество find_all, а затем объединяете их вместе. Моим советом было бы выполнить один find_all, а затем выполнить итерацию по нему. Это намного упрощает построение столбцов вашего фрейма данных, когда все ваши данные находятся в одном месте.

Я обновил приведенный ниже код, чтобы успешно извлекать ссылки без ошибок. С любым кодом существует несколько способов выполнить одну и ту же задачу. Этот вариант, возможно, не самый элегантный, но он выполняет свою работу.

 import requests
from bs4 import BeautifulSoup 
import pandas as pd

r    = requests.get('https://www.raywhite.com/contact/?type=Peopleamp;target=peopleamp;suburb=Sydney, NSW 2000amp;radius=50''amp;firstname=amp;lastname=amp;_so=contact', headers = {'User-agent': 'Super Bot 9000'})
soup = BeautifulSoup(r.text, 'html.parser')

get_cards = soup.find_all("div",{"class":"card horizontal-split vcard"})

agent_list = []

for item in get_cards:
    name      = item.find('li', class_='agent-name').text
    position  = item.find('li', class_='agent-role').text
    phone     = item.find('li', class_='agent-officenum').text
    link      = item.find('li', class_='agent-name').a['href']

    try:
        email = item.find('a',class_='val withicon')['href'].replace('mailto:','')
    except:
        email = 'No Email address'
    agent_list.append({'name':name,'position':position,'email':email,'link':link})

df = pd.DataFrame(agent_list)

  

Выше приведен некоторый пример кода, который я собрал для создания фрейма данных. Ключевым моментом здесь является выполнение одного find_all на "class":"card horizontal-split vcard"}

Надеюсь, это помогло.

Приветствую, Адам