XPATH + XML = Pemrosesan Cepat





Saat melakukan kueri, XPath beroperasi pada entitas seperti node. Node ada beberapa jenis: elemen (node ​​elemen), atribut (node ​​atribut), teks (node ​​teks), namespace (node ​​namespace), instruksi-pemrosesan (node ​​instruksi yang dapat dieksekusi), komentar (node ​​komentar) , dokumen (simpul dokumen).



Mari kita pertimbangkan bagaimana di XPATH urutan node diatur, arah pemilihan dan pemilihan node dengan nilai tertentu.



Untuk memilih node, 6 jenis utama struktur digunakan:







Juga, ketika memilih node, dimungkinkan untuk menggunakan topeng wildcard ketika kita tidak tahu jenis node apa yang harus diambil.







Dalam bahasa XPATH, konstruksi khusus yang disebut sumbu digunakan untuk memilih relatif terhadap simpul saat ini.







Aturan pemilihan dapat berupa absolut (// input [@ placeholder = "Login" - pemilihan dimulai dari simpul akar], atau relatif (* @ class = "okved-table__code" - pemilihan relatif terhadap simpul saat ini). Membuat



aturan pemilihan untuk masing-masing langkah pengambilan sampel dilakukan relatif terhadap node saat ini dan mempertimbangkan:



  • Nama sumbu yang akan diambil sampelnya
  • Kondisi untuk memilih node berdasarkan nama atau posisi
  • Nol atau lebih predikat


Secara umum, sintaks satu langkah pengambilan sampel adalah:



axisname::nodetest[predicate]


Untuk memilih node tertentu untuk beberapa kondisi, parameter atau posisi, alat seperti predikat digunakan. Kondisi predikat diapit oleh tanda kurung siku. Contoh:







Selain konstruksi bahasa XPATH di atas, ini juga berisi dukungan untuk sejumlah operator (+, -, *, div, mod, = ,! =, And, or, etc.), serta lebih dari 200 fungsi bawaan.



Mari kita berikan contoh praktis seperti itu. Kami perlu mengunggah informasi tentang periode daftar orang tertentu. Untuk melakukan ini, kami akan menggunakan layanan notariat.ru.



Kami mengimpor dependensi.



from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
from multiprocessing import Pool
from retry import retry
import itertools, time, pprint, os, re, traceback, sys, datetime
import pandas as pd, numpy as np, multiprocessing as mp


Memuat data tentang orang:



df_people = pd.read_excel('people.xlsx')


Kami mengekstrak informasi dari halaman dengan informasi tentang orang.



def find_persons(driver, name, birth_date):
    base_url = 'https://notariat.ru/ru-ru/help/probate-cases/'
    #    
    driver.get(base_url)
    #       
    driver.find_element_by_xpath('//input[@name="name"]').send_keys(name)
    #       
    driver.find_element_by_xpath('//select[@data-placeholder=""]/following::div/a').click()
   #       
    driver.find_element_by_xpath('//select[@data-placeholder=""]/following::div//li[@data-option-array-index={}]'.format(birth_date.day)).click()
    #       
    driver.find_element_by_xpath('//select[@data-placeholder=""]/following::div/a').click()
   #       
    driver.find_element_by_xpath('//select[@data-placeholder=""]/following::div//li[@data-option-array-index={}]'.format(birth_date.month)).click()
    #      
    driver.find_element_by_xpath('//input[@placeholder=""]').send_keys(str(birth_date.year))
    #  
    driver.find_element_by_xpath('//*[contains(., " ")]').click()
    #   20     ,        «probate-cases__result-list»
    WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CLASS_NAME, "probate-cases__result-list")))
    time.sleep(2)
    
    #      
    max_pages = 1
    pages_counters = driver.find_elements_by_xpath('//a[@class="pagination__item-content"]')
    if pages_counters:
        max_pages = int(pages_counters[-1].text)
    
    data = []
    def parse_page_data():
        #            
        lines = driver.find_elements_by_xpath('//ol[@class="probate-cases__result-list"]/li')
        for line in lines:
            name = ' '.join(map(lambda el: el[0].upper() + el[1:].lower(), line.find_element_by_xpath('.//h4').text.split()))
            death_date = datetime.datetime.strptime(line.find_element_by_xpath('.//p').text.split(':')[-1].strip(), '%d.%m.%Y')
            data.append((name, birth_date, death_date))
    #      
    if max_pages == 1:
        parse_page_data() #         
    else: 
        for page_num in range(1, max_pages + 1):
            #       ,       
            driver.find_element_by_xpath('//li[./a[@class="pagination__item-content" and text()="{}"]]'.format(page_num)).click()
            time.sleep(0.2)
            #      
            parse_page_data()
    return data


Kami melakukan pencarian menggunakan modul multiprocessing untuk mempercepat pengumpulan data.



def parse_persons(persons_data_chunk, pool_num):
    #   Chrome   headless    (      DOM    notariat.ru  )
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--window-size=1920,1080")
    driver = webdriver.Chrome(options=chrome_options)
    driver.set_page_load_timeout(20)
    data = [] 
    print(pool_num, '')
    #         
    for ind, (person_name, person_date) in enumerate(persons_data_chunk, start=1):
        print('pool:', pool_num, ', person: ', ind, '/', len(persons_data_chunk))
        try:
            data.extend(find_persons(driver, person_name, person_date))
        except Exception as e:
            print(pool_num, 'failed to load', person_name, person_date, "error:", e)
            traceback.print_exception(*sys.exc_info()) 
    print(pool_num, 'done')
    return data

def parse(people_data, parts=5):
    p = mp.Pool(parts)
    #               
    people_in_chanks = np.array_split(people_data, parts if parts < len(people_data) else 1) or []
    all_data = p.starmap(parse_persons, zip(people_in_chanks, range(parts)))
    out = []
    for el in all_data:
        out.extend(el)
    return out
parsed_data = parse(people_data)




Dan kami menyimpan hasilnya:



df = pd.DataFrame({
    '': list(map(lambda el: el[0], parsed_data)),
    " ": list(map(lambda el: el[1], parsed_data)),
    ' ': list(map(lambda el: el[2], parsed_data))
})
df.to_excel('results.xlsx', index=False)


Gambar di bawah ini menunjukkan halaman pencarian untuk file pribadi, yang menunjukkan nama lengkap, tanggal lahir, yang kemudian dicari. Setelah memasukkan nama lengkap dan tanggal lahir, algoritme mengklik tombol untuk mencari kasus, setelah itu menganalisis hasilnya.







Pada gambar berikutnya, kita melihat daftar, elemen-elemennya diurai oleh algoritme.







Contoh di atas menunjukkan bagaimana Anda dapat menggunakan XPATH untuk mengumpulkan informasi dari halaman web. Tetapi seperti yang telah disebutkan, XPATH dapat diterapkan untuk memproses dokumen xml apa pun, menjadi standar industri untuk mengakses elemen xml dan xhtml, transformasi xslt.



Sering kali keterbacaan kode memengaruhi kualitasnya, jadi Anda harus meninggalkan ekspresi reguler saat mengurai, mempelajari XPATH, dan mulai menerapkannya dalam alur kerja Anda. Ini akan membuat kode Anda lebih mudah dipahami. Anda akan membuat lebih sedikit kesalahan dan juga mengurangi waktu debugging.



All Articles