Скрипт Python для веб-поиска не выдает ошибку ИЛИ результат. Это проблема запросов или проблема XPATH? - PullRequest
0 голосов
/ 12 мая 2019

Я написал (собрал) сценарий с целью очистки онлайн-графика и создания настольных напоминаний на его основе.Фактическая функция очистки не дает мне ошибки ИЛИ результата.Кажется, работает, но не работает.Это проблема XPATH или я неправильно понял фактическую часть HTML-соединения?

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

from lxml import html
import requests
import ssl
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
payload = { 'username': 'u1000', 'password': 'p1000' }
url = 'https://login.url'
requests.post(url, data=payload, verify=False)

page = requests.get('https://schedule.url', verify=False)
tree = html.fromstring(page.content)

first_appt = tree.xpath('//*[@id="workarea"]/table[2]/tbody/tr[1]/td/table/tbody/tr[3]/td/table/tbody/tr[2]/td/table/tbody/tr[1]/td[4]')

print('First Appt: ', first_appt)
#NO ERRORS BUT NO RESULTS

URL-адреса были изменены для обеспечения конфиденциальности клиента.Я получил XPATH для текста, который мне нужно почистить через INSPECT> COPY XPATH в Chrome.Там есть до 9 временных рамок, которые я собираюсь очистить, и единственная разница между XPATH - это «tr [#]» в конце XPATH.Он увеличивается на единицу для каждой встречи.Я ожидал, что этот скрипт соединится, войдет в систему, найдет XPATH и очистит текст.Вместо этого он выдает:

"First Appt: []"

Как и предполагалось, код изменен на следующий:

from lxml import etree, html
import requests
import ssl
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
payload = { 'username': 'u1000', 'password': 'p1000' }
url = 'https://login.url'
requests.post(url, data=payload, verify=False)

sess = requests.Session()
sess.post(url, data=payload, verify=False)

page = requests.get('https://schedule.url', verify=False)
tree = html.fromstring(page.content)
tree = etree.ElementTree(tree)

#first_appt = tree.xpath('//*[@id="workarea"]/table[2]/tbody/tr[1]/td/table/tbody/tr[3]/td/table/tbody/tr[2]/td/table/tbody/tr[1]/td[4]')
#first_appt = tree.xpath('//*[@id="workarea"]/table[2]/tbody/tr[2]/td/table/tbody/tr[3]/td/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr[1]/td')
#first_appt = tree.xpath('//*[@id="workarea"]/table[1]/tbody/tr/td/table/tbody/tr/td/b') < TOP DATE
first_appt = tree.xpath('//*[@id="plid10575"]/div[2]')
print('First Appt: ', first_appt)

Измененный код выполняется без ошибок, однако результат тот же.Использование разных XPath не изменило результат, что заставило меня поверить, что мое понимание xpath неверно или мой метод определения требуемого xpath неверен.Изменение:

print('First Appt: ', first_appt)

на

print(tree)

было единственным другим результатом, который дал:

# $ py login.py
# <lxml.etree._ElementTree object at 0x04288BE8>

Ответы [ 3 ]

0 голосов
/ 12 мая 2019

Вы проверили, что находится в page.content? Помимо того, что предложил Джеймс, попробуйте преобразовать дерево в ElementTree:

from lxml import etree, html

tree = html.fromstring(page.content)
tree = etree.ElementTree(tree)

Также включите текст () в XPATH

first_appt = tree.xpath('//*[@id="plid10575"]/div[2]text()')
0 голосов
/ 24 мая 2019
from lxml import html
import requests
import ssl
import urllib3

from bs4 import BeautifulSoup

from urllib3.exceptions import InsecureRequestWarning
urllib3.disable_warnings(InsecureRequestWarning)

payload = { 'username': 'u1000', 'password': 'p1000' }
url = 'https://login.url'
requests.post(url, data=payload, verify=False)

page = requests.get('https://schedule.url', verify=False)

soup = BeautifulSoup(page.content, 'lxml')

rows = []
tables = soup.find_all("table")
for table in tables:
    rows = table.find_all("tr")
    for row in rows:
        data = row.find_all("td")
        r = [i.text for i in data]
        rows.append(r)

print('First Appt: ', rows)
0 голосов
/ 12 мая 2019

Я думаю, что основная проблема заключается в том, что возврат из запроса POST к URL-адресу входа нигде не сохраняется. Эта строка:

requests.post(url, data=payload, verify=False)
В

вы вошли в систему, но тот факт, что вы вошли в систему, нигде не сохраняется. Веб-серверы (в основном) не имеют состояния. Они не помнят, кто вошел в систему, а как нет. Это где сессия вступает в игру. Когда вы отправляете запрос POST, сервер отвечает, говоря: «Привет, я знаю, кто вы, вот еще кое-что, что вы можете показать мне теперь, что доказывает, что я вас знаю». То, что он отправляет обратно, является cookie.

В браузере этот файл cookie автоматически сохраняется. В Python вы запрашиваете cookie-файл, используя ваш запрос POST, но не храните его таким образом, чтобы будущие запросы использовали этот cookie-файл, чтобы показать, что вы прошли аутентификацию.

Здесь Session объект вступает в игру. Вы можете сделать GET и POST запросов от Session объекта, и он будет хранить и обрабатывать все административные вещи, такие как куки для вас.

Попробуйте это:

sess = requests.Session()
sess.post(url, data=payload, verify=False)

page = requests.get('https://schedule.url', verify=False)
tree = html.fromstring(page.content)
...