XPath как из нескольких блоков записать в один словарь данные
Хочу собрать данные с страницы, но они все в разных классах/дивах/улах. В ChroPath по данным xpath_string выделяет нужные данные, но как в питоне из xpath_string записать в словарь отдельно для каждого блока наименование, ссылку и т.д.?
если info['name'] = el.xpath('.//*[@text()]') - пусто - ничего не находит,
по коду ниже выдает ошибку по строке info['name']... :
info['name'] = el.xpath('.//*/text()') - выбирает данные только из x1
Код:
from lxml import html
import requests
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45'
headers = {
'User-Agent': user_agent
}
url_mail = 'https://news.mail.ru/'
x1 = '//div[contains(@class, "daynews")]'
x2 = '//ul[contains(@class, "list list_type_square list_half js-module")]//a'
x3 = '//div[contains(@class, "cols__column")]'
xpath_string = f'{x1}|{x2}|{x3}'
r = requests.get(url_mail, headers)
s = r.text
doc = html.fromstring(s)
elem = doc.xpath(xpath_string)
for el in elem:
info = {}
info['name'] = el.xpath(f'.//*({x1}//a//span)[position() < 14]//text()|.//*({x2})[position() > 2]/text()|.//*{x3}//span//a//text()')
print(info)
break
Ошибка:
Traceback (most recent call last):
File "D:\pythonProject\MongoDb\lesson_4-1.py", line 41, in <module>
info['name'] = el.xpath(f'.//*({x1}//a//span)[position() < 14]//text()|.//*({x2})[position() > 2]/text()|.//*{x3}//span//a//text()')
File "src\lxml\etree.pyx", line 1582, in lxml.etree._Element.xpath
File "src\lxml\xpath.pxi", line 305, in lxml.etree.XPathElementEvaluator.__call__
File "src\lxml\xpath.pxi", line 225, in lxml.etree._XPathEvaluatorBase._handle_result
lxml.etree.XPathEvalError: Invalid expression
Ответы (1 шт):
Автор решения: Ольга Паршина
→ Ссылка
решила самостоятельно) Нужно только вывод привести к красивому виду, пока только скопом все выдает. Может кто-нибудь подскажет как лучше сделать?
from lxml import html
import requests
from pprint import pprint
import datetime
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45'
headers = {
'User-Agent': user_agent
}
url_mail = 'https://news.mail.ru/'
x1 = '//div[contains(@class, "daynews")]'
x2 = '//ul[contains(@class, "list list_type_square list_half js-module")]//a'
x3 = '//div[contains(@class, "cols__column")]'
xpath_string = '//div[contains(@class, "block")][position() < 4]'
r = requests.get(url_mail, headers)
s = r.text
doc = html.fromstring(s)
elem = doc.xpath(xpath_string)
print(len(elem))
print(elem)
news = []
for el in elem:
info = {}
info['source'] = url_mail
info['name'] = el.xpath(f'.//*{x1}//a/text()|{x2}/text()|{x3}//span//a//text()')
info['link'] = el.xpath(f'//{x1}//a/@href | {x2}/@href | {x3}//span//a/@href')
info['date'] = datetime.date.today()
news.append(info)