Selenium 및 Python을 사용하여 전단지를 웹 스크랩으로 매핑하는 방법

Sep 10 2020

이 게시물은 다음과 매우 유사합니다. 마우스를 가져간 후 팝업 될 때 셀레늄과 파이썬을 사용하여 데이터 추출

그러나 나는 내가 원하는 답을 찾을 수 없었다.

나는 다음과 매우 유사한 전단지 맵을 웹 스크랩하려고합니다. https://leafletjs.com/examples/choropleth/, 이상적으로는 다각형 위로 마우스를 이동 한 후 나타나는 모든 정보를 다운로드하고 싶습니다.

모든 원 요소에 대해 반복되는 원본 게시물, 모든 다각형에 대해 동일한 작업을 수행하고 싶습니다.

코드 시도 :

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

오류가 발생합니다.

JavascriptException: Message: javascript error: arguments[0].dispatchEvent is not a function
  (Session info: chrome=85.0.4183.102)

"리플릿-인터랙티브"요소에 마우스 오버 이벤트 유형이없는 것처럼 보입니다. 다각형 위로 마우스를 이동하는 사람의 동작을 어떻게 재현 할 수 있습니까?

답변

2 DebanjanB Sep 25 2020 at 03:32

전단지지도를 웹 스크랩하고 다각형 위로 마우스를 이동 한 후 나타나는 모든 정보를 추출하려면 원하는 요소가 안에 <iframe>있으므로 다음을 수행해야합니다.

  • 원하는 프레임을 사용할 수 있도록 WebDriverWait 를 유도 하고 전환합니다 .

  • 원하는 visible_of_element_located에 대해 WebDriverWait 를 유도 합니다 .

  • 다음 로케이터 전략을 사용할 수 있습니다 .

    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)
    
  • 참고 : 다음 가져 오기를 추가해야합니다.

    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 EC
    
  • 콘솔 출력 :

    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
    

참고

다음에서 몇 가지 관련 토론을 찾을 수 있습니다.

  • iframe에서 #document를 처리하는 방법
  • Selenium 및 Python을 통해 iframe으로 전환
Dev Oct 01 2020 at 01:49

엉성하고 오버 헤드 및 긴 실행 대신 모든 데이터를 사용할 수있는 URL을 가져 와서 파싱하십시오.

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)

수입품 필요-

import requests
import json
import jsonpath

산출:-

[{'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}]