Cách lập bản đồ tờ rơi webscrap đa giác bằng Selenium và Python

Sep 10 2020

Bài đăng này khá giống bài đăng này: Sử dụng selen và python để trích xuất dữ liệu khi nó bật lên sau khi di chuột

Nhưng tôi đã không thể tìm thấy câu trả lời mà tôi đã tìm kiếm.

Tôi đang cố gắng tạo sơ đồ tờ rơi trên web rất giống với bản đồ này: https://leafletjs.com/examples/choropleth/, lý tưởng nhất là tôi muốn tải xuống tất cả thông tin xuất hiện sau khi di chuyển chuột qua các đa giác:

Bài đăng gốc lặp lại trên mọi phần tử vòng tròn, tôi sẽ muốn làm như vậy trên mọi đa giác.

Thử nghiệm mã:

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

Tôi gặp lỗi:

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

Có vẻ như các phần tử "tương tác với tờ rơi" không có sự kiện khi di chuột qua, làm cách nào để tôi có thể tái tạo hành động di chuyển chuột của con người qua các đa giác?

Trả lời

2 DebanjanB Sep 25 2020 at 03:32

Để đóng gói trang web bản đồ tờ rơi và trích xuất tất cả thông tin xuất hiện sau khi di chuyển chuột qua các đa giác, vì các phần tử mong muốn nằm trong một, <iframe>vì vậy bạn phải:

  • Kích hoạt WebDriverWait để có sẵn khung mong muốn và chuyển sang khung đó .

  • Tạo ra WebDriverWait để có được khả năng hiển thị mong muốn_of_element_located .

  • Bạn có thể sử dụng các Chiến lược định vị sau:

    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)
    
  • Lưu ý : Bạn phải thêm các lần nhập sau:

    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
    
  • Đầu ra bảng điều khiển:

    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
    

Tài liệu tham khảo

Bạn có thể tìm thấy một số cuộc thảo luận có liên quan trong:

  • Các cách xử lý #document trong iframe
  • Chuyển sang iframe thông qua Selenium và python
Dev Oct 01 2020 at 01:49

Thay vì làm cho quá trình thực thi lộn xộn, tốn công và kéo dài, chỉ cần lấy url nơi tất cả dữ liệu có sẵn và phân tích cú pháp.

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)

Nhập khẩu cần thiết -

import requests
import json
import jsonpath

Đầu ra: -

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