Невозможно получить табличное содержимое с сайта с помощью запросов

#python #python-3.x #web-scraping #python-requests

Вопрос:

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

 <?xml version='1.0' encoding='UTF-8'?>
<partial-response><redirect url="/bc9/web/catalog"></redirect></partial-response>
 

Я пробовал с:

 import requests

link = 'https://cri.nbb.be/bc9/web/catalog?execution=e1s1'

payload = {
    'javax.faces.partial.ajax': 'true',
    'javax.faces.source': 'page_searchForm:actions:0:button',
    'javax.faces.partial.execute': 'page_searchForm',
    'javax.faces.partial.render': 'page_searchForm page_listForm pageMessagesId',
    'page_searchForm:actions:0:button': 'page_searchForm:actions:0:button',
    'page_searchForm': 'page_searchForm',
    'page_searchForm:j_id3:generated_number_2_component': '0466425389',
    'page_searchForm:j_id3:generated_name_4_component': '',
    'page_searchForm:j_id3:generated_address_zipCode_6_component': '',
    'page_searchForm:j_id3_activeIndex': '0',
    'page_searchForm:j_id2_stateholder': 'panel_param_visible;',
    'page_searchForm:j_idt133_stateholder': 'panel_param_visible;',
    'javax.faces.ViewState': 'e1s1'
}
headers = {
    'Faces-Request': 'partial/ajax',
    'X-Requested-With': 'XMLHttpRequest',
    'Origin': 'https://cri.nbb.be',
    'Accept': 'application/xml, text/xml, */*; q=0.01',
    'Accept-Encoding': 'gzip, deflate, br',
    'Host': 'cri.nbb.be',
    'Origin': 'https://cri.nbb.be',
    'Referer': 'https://cri.nbb.be/bc9/web/catalog?execution=e1s1'     
}
with requests.Session() as s:
    s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
    s.get(link)
    s.headers.update(headers)
    res = s.post(link,data=payload)
    print(res.text)
 

Как я могу получить табличное содержимое с этого сайта с помощью запросов?

Ответ №1:

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

Вам не нужно явно устанавливать заголовки, отличные от User-Agent.

Я добавил некоторый код: (а) для извлечения атрибута «action» формы с помощью BeautifulSoup — вы можете сделать это с помощью регулярных выражений, если хотите, (б) для получения URL-адреса из того XML-файла перенаправления, который вы показали в верхней части вашего вопроса.

 import re
from urllib.parse import urljoin

import requests
from bs4 import BeautifulSoup

...

with requests.Session() as s:
    s.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36"

    # GET to get search form
    req1 = s.get(link)
    # Get the form action
    soup = BeautifulSoup(req1.text, "lxml")
    form = soup.select_one("#page_searchForm")
    form_action = urljoin(link, form["action"])

    # POST the form
    req2 = s.post(form_action, data=payload)
    # Extract the target from the redirection xml response
    target = re.search('url="(.*?)"', req2.text).group(1)

    # Final GET to get the search result
    req3 = s.get(urljoin(link, target))

    # Parse and print (some of) the result
    soup = BeautifulSoup(req3.text, "lxml").body
    for detail in soup.select(".company-details tr"):
        columns = detail.select("td")
        if columns:
            print(f"{columns[0].text.strip()}: {columns[1].text.strip()}")
 

Результат:

 Company number: 0466.425.389
Name: A en B PARTNERS
Address: Quai de Willebroeck 37
: BE 1000 Bruxelles
Municipality code NIS: 21004 Bruxelles
Legal form: Cooperative company with limited liability
Legal situation: Normal situation
Activity code (NACE-BEL)
The activity code of the company is the statistical activity code in use on the date of consultation, given by the CBSO based on the main activity codes available at the Crossroads Bank for Enterprises and supplementary informations collected  from the companies: 69201 - Accountants and fiscal advisors
 

Комментарии:

1. «urljoin» может и не потребоваться, я просто всегда использую его

Ответ №2:

Я думаю requests , не удалось обработать динамические веб-страницы. Я использую helium и pandas для выполнения работы.

 import helium as he
import pandas as pd

url = 'https://cri.nbb.be/bc9/web/catalog?execution=e1s1'
driver = he.start_chrome(url)

he.write('0466425389', into='Company number')
he.click('Search')

he.wait_until(he.Button('New search').exists)
he.select(he.ComboBox('10'), '100')
he.wait_until(he.Button('New search').exists)

with open('download.html', 'w') as html:
    html.write(driver.page_source)

he.kill_browser()

df = pd.read_html('download.html')
df[2]
 

Вывод

введите описание изображения здесь