تجريف أفضل للويب في Python باستخدام السيلينيوم والحساء الجميل والباندا

تجريف على شبكة الإنترنت

باستخدام لغة برمجة Python ، من الممكن "كشط" البيانات من الويب بطريقة سريعة وفعالة.

يتم تعريف تجريف الويب على النحو التالي:

أداة لتحويل البيانات غير المهيكلة على الويب إلى بيانات منظمة يمكن قراءتها آليًا وجاهزة للتحليل. (مصدر)

تجريف الويب هو أداة قيمة في مجموعة مهارات عالم البيانات.

الآن ، ماذا تكشط؟

البيانات المتاحة للجمهور

يدعم موقع KanView الإلكتروني "الشفافية في الحكومة". هذا هو أيضا شعار الموقع. يوفر الموقع بيانات كشوف المرتبات لولاية كانساس. وهذا رائع!

ومع ذلك ، مثل العديد من المواقع الحكومية ، فإنها تدفن البيانات في روابط وجداول للتنقيب. يتطلب هذا غالبًا "أفضل تخمين للتنقل" للعثور على البيانات المحددة التي تبحث عنها. أردت استخدام البيانات العامة المقدمة للجامعات داخل كنساس في مشروع بحثي. كان كشط البيانات باستخدام Python وحفظها على هيئة JSON هو ما أحتاجه للبدء.

تزيد روابط JavaScript من التعقيد

غالبًا ما لا يتطلب تجريف الويب باستخدام Python أكثر من استخدام وحدة حساء جميلة للوصول إلى الهدف. Beautiful Soup هي مكتبة لغة Python شائعة تجعل عملية تجريف الويب عن طريق اجتياز DOM (نموذج كائن المستند) أسهل في التنفيذ.

ومع ذلك ، يستخدم موقع KanView على الويب روابط JavaScript. لذلك ، لن تعمل الأمثلة التي تستخدم Python و Beautiful Soup بدون بعض الإضافات الإضافية.

السيلينيوم للإنقاذ

تُستخدم حزمة السيلينيوم لأتمتة تفاعل متصفح الويب من Python. باستخدام السيلينيوم ، يمكن برمجة نص Python لأتمتة متصفح الويب. بعد ذلك ، لم تعد روابط JavaScript المزعجة هذه مشكلة.

from selenium import webdriver from selenium.webdriver.common.keys import Keys from bs4 import BeautifulSoup import re import pandas as pd import os

سيبدأ السيلينيوم الآن جلسة المتصفح. لكي يعمل السيلينيوم ، يجب أن يصل إلى برنامج تشغيل المتصفح. بشكل افتراضي ، سيبحث في نفس الدليل مثل نص بايثون. روابط إلى برامج تشغيل Chrome و Firefox و Edge و Safari متوفرة هنا. يستخدم رمز المثال أدناه Firefox:

#launch url url = "//kanview.ks.gov/PayRates/PayRates_Agency.aspx" # create a new Firefox session driver = webdriver.Firefox() driver.implicitly_wait(30) driver.get(url) python_button = driver.find_element_by_id('MainContent_uxLevel1_Agencies_uxAgencyBtn_33') #FHSU python_button.click() #click fhsu link

ما ورد python_button.click()أعلاه يخبر السيلينيوم أن ينقر على رابط جافا سكريبت على الصفحة. بعد الوصول إلى صفحة عناوين الوظائف ، يسلم السيلينيوم مصدر الصفحة إلى Beautiful Soup.

الانتقال إلى الحساء الجميل

يظل الحساء الجميل هو أفضل طريقة لاجتياز DOM وكشط البيانات. بعد تحديد قائمة فارغة ومتغير عداد ، حان الوقت لأن تطلب من Beautiful Soup الحصول على جميع الروابط الموجودة على الصفحة التي تطابق تعبيرًا عاديًا:

#Selenium hands the page source to Beautiful Soup soup_level1=BeautifulSoup(driver.page_source, 'lxml') datalist = [] #empty list x = 0 #counter for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")): ##code to execute in for loop goes here

يمكنك أن ترى من المثال أعلاه أن Beautiful Soup ستسترجع رابط JavaScript لكل مسمى وظيفي في وكالة الولاية. الآن في كتلة التعليمات البرمجية لحلقة for / in ، سينقر Selenium على كل رابط JavaScript. ثم يقوم حساء جميل باسترداد الجدول من كل صفحة.

#Beautiful Soup grabs all Job Title links for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")): #Selenium visits each Job Title page python_button = driver.find_element_by_id('MainContent_uxLevel2_JobTitles_uxJobTitleBtn_' + str(x)) python_button.click() #click link #Selenium hands of the source of the specific job page to Beautiful Soup soup_level2=BeautifulSoup(driver.page_source, 'lxml') #Beautiful Soup grabs the HTML table on the page table = soup_level2.find_all('table')[0] #Giving the HTML table to pandas to put in a dataframe object df = pd.read_html(str(table),header=0) #Store the dataframe in a list datalist.append(df[0]) #Ask Selenium to click the back button driver.execute_script("window.history.go(-1)") #increment the counter variable before starting the loop over x += 1

الباندا: مكتبة تحليل بيانات بايثون

حساء جميل يمرر النتائج إلى الباندا. يستخدم Pandas read_htmlوظيفته لقراءة بيانات جدول HTML في إطار بيانات. يتم إلحاق إطار البيانات بالقائمة الفارغة المحددة مسبقًا.

قبل اكتمال كتلة التعليمات البرمجية للحلقة ، يحتاج Selenium إلى النقر فوق زر الرجوع في المتصفح. هذا لذا فإن الرابط التالي في الحلقة سيكون متاحًا للنقر على صفحة قائمة الوظائف.

عند اكتمال حلقة for / in ، قام السيلينيوم بزيارة كل رابط مسمى وظيفي. حساء جميل استعاد الجدول من كل صفحة. قام Pandas بتخزين البيانات من كل جدول في إطار بيانات. كل إطار بيانات هو عنصر في قاعدة البيانات. يجب الآن دمج إطارات بيانات الجدول الفردية في إطار بيانات واحد كبير. سيتم بعد ذلك تحويل البيانات إلى تنسيق JSON باستخدام pandas.Dataframe.to_json:

#loop has completed #end the Selenium browser session driver.quit() #combine all pandas dataframes in the list into one big dataframe result = pd.concat([pd.DataFrame(datalist[i]) for i in range(len(datalist))],ignore_index=True) #convert the pandas dataframe to JSON json_records = result.to_json(orient='records')

يقوم Python الآن بإنشاء ملف بيانات JSON. إنه جاهز للاستخدام!

#get current working directory path = os.getcwd() #open, write, and close the file f = open(path + "\\fhsu_payroll_data.json","w") #FHSU f.write(json_records) f.close()

العملية الآلية سريعة

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

كود بايثون الكامل

ها هو كود بايثون الكامل. لقد قمت بتضمين استيراد لجدولة. يتطلب سطرًا إضافيًا من التعليمات البرمجية يستخدم جدولة لطباعة البيانات إلى واجهة سطر الأوامر:

from selenium import webdriver from selenium.webdriver.common.keys import Keys from bs4 import BeautifulSoup import re import pandas as pd from tabulate import tabulate import os #launch url url = "//kanview.ks.gov/PayRates/PayRates_Agency.aspx" # create a new Firefox session driver = webdriver.Firefox() driver.implicitly_wait(30) driver.get(url) #After opening the url above, Selenium clicks the specific agency link python_button = driver.find_element_by_id('MainContent_uxLevel1_Agencies_uxAgencyBtn_33') #FHSU python_button.click() #click fhsu link #Selenium hands the page source to Beautiful Soup soup_level1=BeautifulSoup(driver.page_source, 'lxml') datalist = [] #empty list x = 0 #counter #Beautiful Soup finds all Job Title links on the agency page and the loop begins for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")): #Selenium visits each Job Title page python_button = driver.find_element_by_id('MainContent_uxLevel2_JobTitles_uxJobTitleBtn_' + str(x)) python_button.click() #click link #Selenium hands of the source of the specific job page to Beautiful Soup soup_level2=BeautifulSoup(driver.page_source, 'lxml') #Beautiful Soup grabs the HTML table on the page table = soup_level2.find_all('table')[0] #Giving the HTML table to pandas to put in a dataframe object df = pd.read_html(str(table),header=0) #Store the dataframe in a list datalist.append(df[0]) #Ask Selenium to click the back button driver.execute_script("window.history.go(-1)") #increment the counter variable before starting the loop over x += 1 #end loop block #loop has completed #end the Selenium browser session driver.quit() #combine all pandas dataframes in the list into one big dataframe result = pd.concat([pd.DataFrame(datalist[i]) for i in range(len(datalist))],ignore_index=True) #convert the pandas dataframe to JSON json_records = result.to_json(orient='records') #pretty print to CLI with tabulate #converts to an ascii table print(tabulate(result, headers=["Employee Name","Job Title","Overtime Pay","Total Gross Pay"],tablefmt='psql')) #get current working directory path = os.getcwd() #open, write, and close the file f = open(path + "\\fhsu_payroll_data.json","w") #FHSU f.write(json_records) f.close()

استنتاج

يعد تجريف الويب باستخدام Python and Beautiful Soup أداة ممتازة في مجموعة مهاراتك. استخدم تجريف الويب عندما تكون البيانات التي تريد العمل بها متاحة للجمهور ، ولكن ليس بالضرورة أن تكون متاحة بشكل ملائم. عندما توفر JavaScript أو "تخفي" المحتوى ، فإن التشغيل الآلي للمتصفح باستخدام Selenium سيضمن "رؤية" التعليمات البرمجية الخاصة بك لما يجب أن تراه (كمستخدم). وأخيرًا ، عندما تقوم بكشط جداول مليئة بالبيانات ، فإن الباندا هي مكتبة تحليل بيانات Python التي ستتعامل معها جميعًا.

مرجع:

كانت المقالة التالية مرجعًا مفيدًا لهذا المشروع:

//pythonprogramminglanguage.com/web-scraping-with-pandas-and-beautifulsoup/

تواصل معي في أي وقت على LinkedIn أو Twitter. وإذا أعجبك هذا المقال ، فامنحه بعض التصفيقات. سوف أقدر ذلك بصدق.

//www.linkedin.com/in/davidagray/

ديف جراي (yesdavidgray) | تويتر

أحدث التغريدات من ديف جراي (yesdavidgray). مدرسFHSUInformatics * مطور * موسيقي * رائد أعمال * ...

twitter.com