Come eseguire il webscrap del depliant mappare i poligoni utilizzando Selenium e Python
Questo post è abbastanza simile a questo: Utilizzo di selenio e python per estrarre i dati quando si apre dopo il passaggio del mouse
Ma non sono riuscito a trovare la risposta che cercavo.
Sto cercando di ritagliare una mappa di volantini molto simile a questa: https://leafletjs.com/examples/choropleth/, idealmente mi piacerebbe scaricare tutte le informazioni che appaiono dopo aver spostato il mouse sui poligoni:
Post originale in loop su ogni elemento del cerchio, mi piacerebbe fare lo stesso su ogni poligono.
Prove del codice:
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome
driver.get("https://leafletjs.com/examples/choropleth/")
timeout = 1000
explicit_wait30 = WebDriverWait(driver, 30)
try:
# Wait for all circles to load
poli = explicit_wait30.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.leaflet-interactive')))
except TimeoutException:
driver.refresh()
data = []
i=1
for circle in poli:
i+=1
# Execute mouseover on the element
driver.execute_script("const mouseoverEvent = new Event('mouseover');arguments[0].dispatchEvent(mouseoverEvent)", poli)
# Wait for the data to appear
listing = explicit_wait30.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '#listingHover')))
data.append(listing.text)
# Close the listing
driver.execute_script("arguments[0].click()", listing.find_element_by_tag_name('button'))
print(i)
if i>15 :
break
Ottengo errore:
JavascriptException: Message: javascript error: arguments[0].dispatchEvent is not a function
(Session info: chrome=85.0.4183.102)
Sembra che gli elementi "leaflet-interactive" non abbiano il tipo di eventi su cui si passa il mouse, come posso riprodurre l'azione umana di spostare il mouse sui poligoni?
Risposte
Per eseguire il webscrap della mappa del volantino ed estrarre tutte le informazioni che appaiono dopo aver spostato il mouse sui poligoni, poiché gli elementi desiderati sono all'interno di un <iframe>quindi è necessario:
Indurre WebDriver Attendi che il frame desiderato sia disponibile e passa ad esso .
Indurre WebDriverWait per la visibilità_di_elemento_locato desiderata .
Puoi utilizzare le seguenti strategie di localizzazione :
driver.get('https://leafletjs.com/examples/choropleth/') driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//h2[text()='Interactive Choropleth Map']")))) WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src='example.html']"))) elements = driver.find_elements_by_css_selector("svg.leaflet-zoom-animated>g path") for element in elements: ActionChains(driver).move_to_element(element).perform() print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='info leaflet-control']"))).text)Nota : devi aggiungere le seguenti importazioni:
from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as ECUscita console:
US Population Density Alabama 94.65 people / mi2 US Population Density Hover over a state US Population Density Arizona 57.05 people / mi2 US Population Density Arkansas 56.43 people / mi2 US Population Density California 241.7 people / mi2 US Population Density Colorado 49.33 people / mi2 US Population Density Connecticut 739.1 people / mi2 US Population Density Delaware 464.3 people / mi2 US Population Density Maryland 596.3 people / mi2 US Population Density Hover over a state US Population Density Georgia 169.5 people / mi2 US Population Density Hover over a state US Population Density Montana 6.858 people / mi2 US Population Density Illinois 231.5 people / mi2 US Population Density Indiana 181.7 people / mi2 US Population Density Iowa 54.81 people / mi2 US Population Density Kansas 35.09 people / mi2 US Population Density Kentucky 110 people / mi2 US Population Density Mississippi 63.5 people / mi2 US Population Density Maine 43.04 people / mi2 US Population Density Virginia 204.5 people / mi2 US Population Density Massachusetts 840.2 people / mi2 US Population Density
Riferimento
Puoi trovare un paio di discussioni rilevanti in:
- Modi per gestire #document in iframe
- Passa a un iframe tramite Selenium e Python
Invece di renderlo instabile, sovraccarico e lungo, prendi l'URL in cui sono disponibili tutti i dati e analizzalo.
Url = 'https://leafletjs.com/examples/choropleth/us-states.js'
response = requests.get(Url)
json_data = json.loads(response.text.split("=")[1].replace(';',''))
prop = jsonpath.jsonpath(json_data,"$.features[*].properties")
print(prop)
Importazioni necessarie -
import requests
import json
import jsonpath
Produzione:-
[{'name': 'Alabama', 'density': 94.65}, {'name': 'Alaska', 'density': 1.264}, {'name': 'Arizona', 'density': 57.05}, {'name': 'Arkansas', 'density': 56.43}, {'name': 'California', 'density': 241.7}, {'name': 'Colorado', 'density': 49.33}, {'name': 'Connecticut', 'density': 739.1}, {'name': 'Delaware', 'density': 464.3}, {'name': 'District of Columbia', 'density': 10065}, {'name': 'Florida', 'density': 353.4}, {'name': 'Georgia', 'density': 169.5}, {'name': 'Hawaii', 'density': 214.1}, {'name': 'Idaho', 'density': 19.15}, {'name': 'Illinois', 'density': 231.5}, {'name':
'Indiana', 'density': 181.7}, {'name': 'Iowa', 'density': 54.81}, {'name': 'Kansas', 'density': 35.09}, {'name': 'Kentucky', 'density': 110}, {'name': 'Louisiana', 'density': 105}, {'name': 'Maine', 'density': 43.04}, {'name': 'Maryland', 'density': 596.3}, {'name': 'Massachusetts', 'density': 840.2}, {'name': 'Michigan', 'density': 173.9}, {'name': 'Minnesota', 'density': 67.14}, {'name': 'Mississippi', 'density': 63.5}, {'name': 'Missouri', 'density': 87.26}, {'name': 'Montana', 'density': 6.858}, {'name': 'Nebraska', 'density': 23.97}, {'name': 'Nevada', 'density': 24.8}, {'name': 'New Hampshire', 'density': 147}, {'name': 'New Jersey', 'density': 1189}, {'name': 'New Mexico', 'density': 17.16}, {'name': 'New York', 'density': 412.3}, {'name': 'North Carolina', 'density': 198.2}, {'name': 'North Dakota', 'density': 9.916}, {'name': 'Ohio', 'density': 281.9}, {'name': 'Oklahoma', 'density': 55.22}, {'name': 'Oregon', 'density': 40.33}, {'name': 'Pennsylvania', 'density': 284.3}, {'name': 'Rhode Island', 'density': 1006}, {'name': 'South Carolina', 'density': 155.4}, {'name': 'South Dakota', 'density': 98.07}, {'name': 'Tennessee', 'density': 88.08}, {'name': 'Texas', 'density': 98.07}, {'name': 'Utah', 'density': 34.3}, {'name': 'Vermont', 'density': 67.73}, {'name': 'Virginia', 'density': 204.5}, {'name': 'Washington', 'density': 102.6}, {'name': 'West Virginia', 'density': 77.06}, {'name': 'Wisconsin', 'density': 105.2}, {'name': 'Wyoming', 'density': 5.851}, {'name': 'Puerto Rico', 'density': 1082}]