Cách lập bản đồ tờ rơi webscrap đa giác bằng Selenium và Python
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
Để đó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
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}]