Разбор HTML с Python. запросы и LXML - PullRequest
0 голосов
/ 04 апреля 2020

Итак, я пытаюсь проанализировать страницу HTML для извлечения двух фрагментов данных из неупорядоченного списка.

На странице есть тысячи <li> элементов, имеющих следующую структуру. .

            <li>
            <a href="/lesson/check/119" target="_blank">
                Check lesson <b>#119</b> "structure-of-the-blood-vessels"
            </a>
        </li>

Это код Python, который я получил до сих пор ...

import requests
from lxml import html

auth = {
  'user_login_form[_username]'      : 'USERNAME',
  'user_login_form[_plainPassword]' : 'PASSWORD',
  'user_login_form[csrf_token]'     : 'TOKEN'
  }

login_url = 'https://example.com/login'
page_url = 'https://example.com/lesson/list'

session = requests.Session()

p = session.post(
  login_url,
  data=auth
  )

print('Connecting to site ...',p.ok)

r = session.get(
  page_url
  )

print('Connecting to page ...',r.ok)

# Parsing text of the webpage into a DOM tree
tree = html.fromstring(r.text)
collection = tree.xpath('//li/a/descendant::text()')

for element in collection:
  print(element)

... и вывод, который я получаю из этого ...


                Check lesson 
#106
 "functions-of-the-skeleton-4"


                Check lesson 
#107
 "classification-of-bones-1"


... et c.

Вывод, который я хочу получить из скрипта, будет ...

106,functions-of-the-skeleton-4

Затем я хочу следовать URL-адресу каждого <li><a> тег для получения одного фрагмента информации с этой страницы ...

    <h1 class="head-h1" style="padding: 1%;">Lesson #106 - Functions of the Skeleton</h1>

... поэтому последняя строка данных, сгенерированных сценарием, будет ...

106,functions-of-the-skeleton-4,Functions of the Skeleton

По сути, я пытаюсь убедиться, что «слаг» для урока на первой странице совпадает с названием урока на дочерней странице.

Пожалуйста, не могли бы вы помочь с XPATH / Python

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Спасибо за вашу помощь - после небольшой проб и ошибок с кодом Python мне удалось заставить его работать идеально (заменив последнюю часть кода Python выше) ...

# Parsing text of the webpage into a DOM tree
tree = html.fromstring(r.text)
collection = tree.xpath('//li') # collection of all li tags

for element in collection:
  lesson_no = element.xpath('substring-after(a/b,"#")') # lesson number
  slug = element.xpath('translate(normalize-space(a/text()[2]),\'"\',"")') # slug
  subpage_url = 'https://example.com'+element.xpath('a/@href')[0] # subpage
  s = session.get(subpage_url) # connect to subpage
  subpage_title = html.fromstring(s.text).xpath('substring-after(//h1/text()," - ")') # title
  line = lesson_no + ',' + slug + ',' + subpage_title
  print(line)

... печатает ...

106,functions-of-the-skeleton-4,Functions of the Skeleton
107,classification-of-bones-1,Classification of Bones
108,structure-of-the-skeleton-1,Structure of the Skeleton
109,classification-of-joints-3,Classification of Joints
110,movement-patterns-2,Movement Patterns

Прекрасно! Мой босс будет доволен! Mark

0 голосов
/ 04 апреля 2020

Относительно части XPath. Для каждого элемента:

Создайте первую часть вашей последней строки с помощью:

concat(//b,",",translate(normalize-space(//a/text()[2]),'"',""),",")

(Выход: 106, functions-of-the-the-skleton-4,).

Сохранить значение // b / text (# 106) в объекте (например, 'foo'). Затем на 2-й странице получите то, что вам нужно, с помощью

normalize-space(substring-after(//h1[contains(.,{foo})],"-"))

(Вывод: функции скелета). Объедини два предыдущих результата, чтобы получить окончательную строку данных.

...