今天為大家介紹的是關於使用Python進行Web爬取和資料提取的內容。我們首先是要清楚地瞭解任務。他們希望我們從中抓取資料,然後將其儲存在CSV檔案中,其中上面列出的我們將抓取資訊:日期(“以下資訊反映了終止{日期}的FMCSA管理資訊系統的內容”),執行狀態,合法名稱,DBA名稱,實際地址,郵寄地址,USDOT號,動力單元,車手。
步驟1:瞭解任務
我們可以提供100個DOT號碼的初始設定,以確保可以輕鬆地刮除上面的資訊,從那裡我們可以提供每天要刮擦的所有DOT號碼。
報告頁面可以通過點或其他名稱ID進行訪問。每個頁面都有自己的ID(點)。因此,這些點位於Excel檔案中。我們必須閱讀此檔案並從中提取點,然後將其傳遞到URL以訪問報告頁面。
第2步:建立環境並安裝依賴項
現在,我們知道了客戶希望從我們這裡得到什麼,因此讓我們建立虛擬環境,然後檢查將要爬網的元素。
要建立virtualenv,請在終端中執行以下命令:
虛擬環境
然後安裝BeautifulSoup(這是一個用於解析HTML和XML文件的Python包)和xlrd(這是一個用於從Excel檔案讀取資料並設定資訊格式的庫):
pip install beautifulsoup4 xlrd
步驟3:檢索資料
好了,開發人員!讓我們從開啟專案描述的示例URL開始,剎車可以看到細分。
我們的第一個目標是查詢-日期(“以下資訊反映了終止{日期}的FMCSA管理資訊系統的內容”)
以下資訊反映了截止日期01/01/2020的FMCSA管理資訊系統的內容。
事實是,我們無法通過特定的類名或ID來檢索此元素。不幸的是,此報告頁面隱藏混亂。
但是,我們可以將它們全部作為文字進行爬網,並使用RegEx提取所需的資料。
正規表示式(RegEx)是特殊的字元序列,可使用模式中保留的特殊語法來幫助您匹配或查詢其他字串或字串集。
日期位於之間。以下資訊反映了FMCSA管理資訊系統的開始日期,以及..(點)。因此,要輸入日期正規表示式將在這些字串之間查詢。
import re#regeximport urllib.request from urllib.request import urlopen,Requestfrom bs4 import BeautifulSoupdef crawl_data(url):
req = Request(URL,標頭= {‘User-Agent’:’Mozilla / 5.0’})www.zpedu.com/
html = urlopen(req).read()
bs = BeautifulSoup(html,’html.parser’)
#查詢所有粗體文字
bold_texts = bs.find_all(‘b’)
對於b在bold_texts中:
嘗試:
#在這些字串之間看
date = re.search(‘以下資訊反映了FMCSA管理資訊系統自(。*)起的內容。’,b.get_text(strip = True,分隔符=’’))。group(1).strip( )
#如果正規表示式找到多個點,則在第一個點之前提取字串
如果len(date)> 11:
日期= date.split(“。”,1)[0]
列印(日期)
除了AttributeError:
通過
好吧,如果您執行該程式,您將看到它正在列印日期。快速向您展示正規表示式的工作原理,因為我有些人想了解。
考慮以下程式碼:
匯入
#我們需要從字串中提取“ coderasha”
data =“您好,我叫Coderasha。”
名稱= re.search(‘你好我的名字是(。*)。’,資料)
列印(名稱)
#輸出:<_sre.SRE_Match物件;span =(0,27),match =’你好,我叫Coderasha。’>
group(1)將其中正規表示式匹配的文字捕獲到一個編號組中,該編號組可以與編號後向引用一起重用
匯入
#我們需要從字串中提取“ coderasha”
data =“您好,我叫Coderasha。”
名稱= re.search(‘你好我的名字是(。*)。’,資料).group(1)
列印(名稱)
#輸出:coderasha
因此,我正在應用相同的邏輯來查詢爬網的序列中的日期。
但是,我們必須使用RegEx再次查詢資料,因為表元素沒有任何特殊屬性。
#獲取表格內的所有文字
資訊= bs.find(‘中心’).get_text(strip =真,分隔符=’’)#使用RegEx查詢欄位
Operating = re.search(‘Operating Status:(。*)Out’,information).group(1).strip()
legal_name = re.search(‘法律名稱:(。*)DBA’,資訊).group(1).strip()
physical_address = re.search(‘Physical Address:(。*)Phone’,information).group(1).strip()
mailing_address = re.search(‘郵件地址:(。*)USDOT’,資訊).group(1).strip()
usdot_address = re.search(‘USDOT號:(。*)國家運營商ID號’,資訊).group(1).strip()
power_units = re.search(‘Power Units:(。*)Drivers’,information).group(1).strip()
drivers = re.search(‘Drivers:(。*)MCS-150表格日期’,資訊).group(1).strip()
步驟4:以CSV格式寫入資料
抓取資料後,就該建立新的csv檔案連結資料寫入其中了。我更喜歡建立另一個函式來處理此操作。
匯入csvdef write_csv(日期,執行,legal_name,實體地址,mailing_address,usdot_address,power_units,驅動程式):
使用open(usdot_address +’.csv’,mode =’w’,newline =’’,encoding =“ utf-8”)作為csv_file:
欄位名稱= [“日期”,“執行狀態”,“法律名稱”,“實體地址”,“郵寄地址”,“動力裝置”,“驅動程式”]
writer = csv.DictWriter(csv_file,fieldnames = fieldnames)
writer.writeheader()
writer.writerow({‘’Date’:date,’Operating Status’:Operating,’Legal_Name’:legal_name,’Physical Address’:physical_address,’Mailing Address’:mailing_address,’Power Units:power_units,’Drivers’:drivers })
CSV名稱必須唯一,因此我用usdot_address或使用已抓取資料的報告頁面的其他名稱ID。
步驟5:讀取Excel檔案以抓取每個點的資料
最後一步是讀取excel檔案,將這些點傳遞到URL的末尾以訪問頁面。我們可以用xlrd讀取Excel檔案。
匯入xlrd
點= [] def read_excel_file():
loc =(“ dots.xls”)
wb = xlrd.open_workbook(loc)
工作表= wb.sheet_by_index(0)
sheet.cell_value(0,0)
#Excel中的前五個點
對於我在範圍(1,5)中:
#將浮點數轉換為字串並從.0清除
點= str(sheet.cell_value(i,0))。replace(‘。0’,’’)
dots.append(dot)
xlrd將數字讀取為浮點數,因此最好的解決方案是將數字轉換為字串並使用
更換()
刪除字串.0結尾將這些點傳遞到url中的方法:
對於點中的點:
crawl_data
#睡眠5秒,避免任何錯誤
time.sleep(5)
這是完整程式碼:
匯入重新匯入csv匯入urllib.request從urllib.request匯入urlopen,Requestfrom bs4匯入BeautifulSoupimport xlrd匯入時間
點= [] def read_excel_file():
loc =(“ dots.xls”)
wb = xlrd.open_workbook(loc)
工作表= wb.sheet_by_index(0)
sheet.cell_value(0,0)
對於我在範圍(1,5)中:
點= str(sheet.cell_value(i,0))。replace(‘。0’,’’)
dots.append(dot)def crawl_data(url):
req = Request(URL,標頭= {‘User-Agent’:’Mozilla / 5.0’})
html = urlopen(req).read()
bs = BeautifulSoup(html,’html.parser’)
bold_texts = bs.find_all(‘b’)
對於b在bold_texts中:
嘗試:
date = re.search(‘以下資訊反映了FMCSA管理資訊系統自(。*)起的內容。’,b.get_text(strip = True,分隔符=’’))。group(1).strip( )
如果len(date)> 11:
日期= date.split(“。”,1)[0]
列印(日期)
除了AttributeError:
通過
資訊= bs.find(‘中心’).get_text(strip =真,分隔符=’’)
Operating = re.search(‘Operating Status:(。*)Out’,information).group(1).strip()
legal_name = re.search(‘法律名稱:(。*)DBA’,資訊).group(1).strip()
physical_address = re.search(‘Physical Address:(。*)Phone’,information).group(1).strip()
mailing_address = re.search(‘郵件地址:(。*)USDOT’,資訊).group(1).strip()
usdot_address = re.search(‘USDOT號:(。*)國家運營商ID號’,資訊).group(1).strip()
power_units = re.search(‘Power Units:(。*)Drivers’,information).group(1).strip()
drivers = re.search(‘Drivers:(。*)MCS-150表格日期’,資訊).group(1).strip()
def write_csv(日期,運作,法定名稱,實體地址,mailing_address,usdot_address,power_units,驅動程式)def write_csv(日期,運作,合法名稱,實體地址,mailing_address,usdot_address,power_units,驅動程式):
使用open(usdot_address +’.csv’,mode =’w’,newline =’’,encoding =“ utf-8”)作為csv_file:
欄位名稱= [“日期”,“執行狀態”,“法律名稱”,“實體地址”,“郵寄地址”,“動力裝置”,“驅動程式”]
writer = csv.DictWriter(csv_file,fieldnames = fieldnames)
writer.writeheader()
writer.writerow({‘’Date’:date,’Operating Status’:Operating,’Legal_Name’:legal_name,’Physical Address’:physical_address,’Mailing Address’:mailing_address,’Power Units:power_units,’Drivers’:drivers })
read_excel_file()
以點為單位列印(點):
crawl_data
time.sleep(5)
任務完成!
本作品採用《CC 協議》,轉載必須註明作者和本文連結