Estoy tratando de ejecutar un programa de Python en una base de datos web para obtener la tabla de resultados. Mi pregunta es ¿cómo podría obtener los resultados sin abrir un navegador? ¿Y hay una manera más fácil de obtener los resultados de la tabla? Quiero obtener el valor de la tabla inferior (por ejemplo, clase BCS, solubilidad, dosis, etc.). (La parte inferior de los resultados no tiene td.text, por lo que no puedo usar el comando find next sibling). ¡Gracias! Aquí está mi código:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup

driver= webdriver.Chrome()
driver.get('http://www.ddfint.net/search.cfm')
search_form=driver.find_element_by_name('compoundName')
search_form.send_keys('Abacavir')
search_form.submit()

page= BeautifulSoup(driver.page_source, 'html.parser')
page.find("td", text="Lowest Solubility (mg/ml):").find_next_sibling("td").text
2
yangm 7 oct. 2019 a las 23:55

3 respuestas

La mejor respuesta

Puede usar el módulo solicitudes. Hay un problema para obtener el texto Clase BCS (logP) porque el HTML está roto en los datos de la tabla Clase BCS . La solución es usar html5lib como un analizador sintáctico.

import requests
from bs4 import BeautifulSoup
import re

headers = {
    'Connection': 'keep-alive',
    'Pragma': 'no-cache',
    'Cache-Control': 'no-cache',
    'Origin': 'http://www.ddfint.net',
    'Upgrade-Insecure-Requests': '1',
    'DNT': '1',
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/77.0.3865.90 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,'
              'application/signed-exchange;v=b3',
    'Referer': 'http://www.ddfint.net/search.cfm',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'ru,en-US;q=0.9,en;q=0.8,tr;q=0.7',
}

data = {
    'compoundName': 'Abacavir',
    'category': '',
    'subcategory': '',
    'Submit': 'Search'
}

response = requests.post('http://www.ddfint.net/results.cfm', headers=headers, data=data, verify=False)
page = BeautifulSoup(response.text, 'html5lib')
print(page.find("td", text="Lowest Solubility (mg/ml):").find_next_sibling("td").text)

# get header row
header_row = page.find("td", text="Country List:").find_parent("tr")
# get columns names, remove : and *
header_data = [re.sub("[:*]", "", td.text.strip()) for td in header_row.find_all("td")]

country_index = header_data.index("Country List")
solubility_index = header_data.index("Solubility")
bcs_class_clogp_index = header_data.index("BCS Class (cLogP)")
bcs_class_logp_index = header_data.index("BCS Class (logP)")

row = header_row
while True:
    # check if next row exist
    row = row.find_next_sibling("tr")
    if not row:
        break

    # collect row data
    row_data = [td.text.strip() for td in row.find_all("td")]
    print(row_data[country_index], row_data[solubility_index],
          row_data[bcs_class_clogp_index], row_data[bcs_class_logp_index])

Código con pandas:

import requests
from bs4 import BeautifulSoup
import re
import pandas as pd

headers = {
    'Connection': 'keep-alive',
    'Pragma': 'no-cache',
    'Cache-Control': 'no-cache',
    'Origin': 'http://www.ddfint.net',
    'Upgrade-Insecure-Requests': '1',
    'DNT': '1',
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/77.0.3865.90 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,'
              'application/signed-exchange;v=b3',
    'Referer': 'http://www.ddfint.net/search.cfm',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'ru,en-US;q=0.9,en;q=0.8,tr;q=0.7',
}

data = {
    'compoundName': 'Abacavir',
    'category': '',
    'subcategory': '',
    'Submit': 'Search'
}

response = requests.post('http://www.ddfint.net/results.cfm', headers=headers, data=data, verify=False)
page = BeautifulSoup(response.text, 'html5lib')
print(page.find("td", text="Lowest Solubility (mg/ml):").find_next_sibling("td").text)

# get header row
header_row = page.find("td", text="Country List:").find_parent("tr")
# get columns names, and remove : and *
header_data = [re.sub("[:*]", "", td.text.strip()) for td in header_row.find_all("td")]

# loop while there's row after header row
data = []
row = header_row
while True:
    # check if next row exist
    row = row.find_next_sibling("tr")
    if not row:
        break

    # collect row data
    row_data = [td.text.strip() for td in row.find_all("td")]
    data.append(row_data)

# create data frame
df = pd.DataFrame(data, columns=header_data)
3
Sers 7 oct. 2019 a las 23:28

Puede intentar agregar el argumento --headless a ChromeOptions para indicarle al navegador que no procese.

from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(chrome_options=chrome_options)
8
Christine 7 oct. 2019 a las 21:01

Puede dejar el selenio sin cabeza agregando una opción (--headless) como esta:

from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome(chrome_options=chrome_options)

Y sobre la iteración a través de una tabla, puede seleccionar todas las filas de la tabla y tomar solo la relevante como esta:

from selenium.webdriver.common.by import By
rows = table_id.find_elements(By.TAG_NAME, "tr")
myrow = rows[5]
2
Dima Daron 7 oct. 2019 a las 22:06
58277020