XPATH + XML = معالجة سريعة





عند تنفيذ الاستعلامات ، يعمل XPath على كيانات مثل العقد. العقد من عدة أنواع: عنصر (عقدة عنصر) ، سمة (عقدة سمة) ، نص (عقدة نصية) ، مساحة الاسم (عقدة مساحة الاسم) ، تعليمات المعالجة (عقدة تعليمات قابلة للتنفيذ) ، تعليق (عقدة تعليق) ، المستند (عقدة المستند).



دعونا نفكر في كيفية تعيين تسلسل العقد في XPATH واتجاهات التحديد واختيار العقد بقيم محددة.



لتحديد العقد ، يتم استخدام 6 أنواع أساسية من الهياكل بشكل أساسي:







أيضًا ، عند اختيار العقد ، من الممكن استخدام أقنعة أحرف البدل عندما لا نعرف نوع العقدة التي يجب أن تأخذها.







في لغة XPATH ، يتم استخدام بنية خاصة تسمى المحور لتحديد نسبة إلى العقدة الحالية.







يمكن أن تكون قاعدة التحديد إما مطلقة (// input [@ placeholder = "Login" - تحديد يبدأ من العقدة الجذرية] ، أو نسبيًا (* @ class = "okved-table__code" - تحديد متعلق بالعقدة الحالية).



بناء قاعدة تحديد لكل منها يتم تنفيذ خطوة أخذ العينات بالنسبة للعقدة الحالية وتأخذ في الاعتبار:



  • اسم المحور المراد أخذ عينة حوله
  • شرط لاختيار عقدة بالاسم أو الموقع
  • صفر أو أكثر المسندات


بشكل عام ، تكون صيغة خطوة أخذ العينات هي:



axisname::nodetest[predicate]


لتحديد عقد معينة لبعض الشروط أو المعلمات أو المواضع ، يتم استخدام أداة مثل المسندات. الشرط الأصلي محاط بأقواس مربعة. أمثلة:







بالإضافة إلى تراكيب لغة XPATH المذكورة أعلاه ، فإنها تحتوي أيضًا على دعم لعدد من العوامل (+ ، - ، * ، div ، mod ، = ،! = ، و ، أو ، إلخ) ، بالإضافة إلى أكثر من 200 وظيفة مضمنة.



دعونا نعطي مثل هذا المثال العملي. نحتاج إلى تحميل معلومات حول فترات قائمة معينة من الأشخاص. للقيام بذلك ، سوف نستخدم خدمة notariat.ru.



نحن نستورد التبعيات.



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


تحميل البيانات على الأشخاص:



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


نحن نستخرج المعلومات من الصفحات التي تحتوي على معلومات عن الأشخاص.



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


نقوم بإجراء عمليات البحث باستخدام وحدة المعالجة المتعددة لتسريع عملية جمع البيانات.



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)




ونحفظ النتائج:



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)


يوضح الشكل أدناه صفحة البحث عن الملفات الشخصية ، والتي تشير إلى الاسم الكامل وتاريخ الميلاد ، والتي يتم البحث عنها لاحقًا. بعد إدخال الاسم الكامل وتاريخ الميلاد ، تنقر الخوارزمية على الزر للبحث عن حالة ، وبعد ذلك تقوم بتحليل النتائج.







في الشكل التالي ، نرى قائمة ، يتم تحليل عناصرها بواسطة الخوارزمية.







يوضح المثال أعلاه كيف يمكنك استخدام XPATH لتجميع المعلومات من صفحات الويب. ولكن كما ذكرنا سابقًا ، فإن XPATH قابل للتطبيق لمعالجة أي مستندات xml ، كونه المعيار الصناعي للوصول إلى عناصر xml و xhtml ، تحويلات xslt.



غالبًا ما تؤثر قابلية قراءة التعليمات البرمجية على جودتها ، لذلك يجب عليك التخلي عن التعبيرات العادية عند التحليل ودراسة XPATH والبدء في تطبيقه في سير عملك. هذا سيجعل الكود الخاص بك أسهل في الفهم. سترتكب أخطاء أقل وستقلل أيضًا من وقت التصحيح.



All Articles