Я совершенно новичок в этом, поэтому я действительно не знаю, возможно ли это:
Эта веб-страница имеет заголовки под 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, поэтому, возможно, я пропустил простой способ сделать это.
Если вы не застряли в 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...)