lxml и xpath в python: получить пары h3 и электронной почты из html-документа в списке с возможной отсутствующей электронной почтой

0

Я совершенно новичок в этом, поэтому я действительно не знаю, возможно ли это:

Эта веб-страница имеет заголовки под h3, легко получить с lxml:

titles=doc.xpath("//div/h3/a/text())

у них есть электронные письма:

emails=doc.xpath("//div/p[text()='Email: ']/a/text()")

И я могу объединить их в список с '|':

both=doc.xpath("//div/h3/a/text()|//div/p[text()='Email: ']/a/text()")

Проблема в том, что некоторые результаты не имеют электронной почты, поэтому я получаю плохой список, а некоторые заголовки не следует по электронной почте, а с другим заголовком, даже без пустого элемента списка. Я могу работать над этим с некоторой обработкой, но мне интересно, может ли его вернуть "не найденный", когда отсутствует электронная почта, поэтому я получаю работоспособные пары: название-электронная почта, название не найдено и т.д.

Я попробовал рецепт, который я нашел здесь, используя:

emails=doc.xpath("concat(//div/p[text()='Email: ']/a/text(),substring('not-found',1 div not(//div/p[text()='Email: ']/a/text())))")

Но это работает только как автономное с электронными письмами, если я смешиваю его с '|' Я получаю ошибку XPathEvalError: недопустимый тип.

для записи это то, что я пробовал:

emails=doc.xpath("//div/h3/a/text()|concat(//div/p[text()='Email: ']/a/text(),substring('not-found',1 div not(//div/p[text()='Email: ']/a/text())))")

Я новичок в lxml и xpath, поэтому, возможно, я пропустил простой способ сделать это.

  • 0
    Можете ли вы показать нам пример HTML-файла, который вы хотите проанализировать?
  • 0
    да, это публичный каталог парикмахерских предприятий в Испании, вы можете посмотреть здесь: основные ссылки
Показать ещё 1 комментарий
Теги:
xpath
screen-scraping
lxml

1 ответ

1
Лучший ответ

Если вы не застряли в lxml, вы можете попробовать BeautifulSoup. Мне легче его использовать. Я просмотрел эту страницу, но не смог разобрать ее, потому что у нее есть заголовок xml непосредственно перед заголовком html, например:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ES" xml:lang="ES" >
...

Мне пришлось удалить первую строку (заголовок xml), чтобы проверить ее. Сказал, что здесь у вас есть пример с BeautifulSoup:

from urllib.request import urlopen
from bs4 import BeautifulSoup
from itertools import dropwhile
import re

html = urlopen('http://www.datosempresa.com/Categoria/peluqueria?pagina=4').read()
soup = BeautifulSoup(html, 'html')

for div in soup.find_all('div', attrs={'class':'resultados'}):
    title = div.find_next('h3').string
    email = list(dropwhile(lambda x: not re.match(r'(?i)email:', x), div.strings))
    print('{} - {}'.format(title, email[1] if email else 'Not found'))

Он ищет все элементы <div> с атрибутом class с resultados как значением, извлекает все строки из своих дочерних элементов и удаляет все найденные до того, что соответствует email: игнорирование case. Если возвращаемый список пуст, просто нажмите " Not found, иначе электронное письмо станет вторым элементом в списке, поэтому извлеките его.

Запустите его так:

python3 script.py

Это дает:

MANUELA RIVERO - [email protected]
SALON DE BELLEZA LIDIA - Not found
TRUKO & HAIR DESIGN - Not found
PACO PERFUMERIAS - [email protected]
ESTHER CENDAGORTAGALARZA ESTILISTA - [email protected]
ADARIS - [email protected]
N&K NAILS - [email protected]
PELUQUERIA NELA - [email protected]
PELUQUERIA NELA - [email protected]
PELUQUERIA HUMBERTO STAR - [email protected]
COLLADOS PELUQUEROS - [email protected]
ZEN NATURE ESTéTICA - [email protected]
LA CASA DE MAR - Not found
DELGADO PERRUQUERS - Not found
(...output cut to save space...)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню