Python使用爬蟲技術時,每運行一次,本地都會訪問一次主機。為避免完成程序前調試時多次訪問主機增加主機負荷,我們可以在編寫程序前將網頁源代碼存在本地,調試時訪問本地文件即可。現在我來分享一下爬取資料的調試過程。
一、將網頁源代碼存在本地
1、打開需要爬取的網頁,鼠標右鍵查看源代碼
2、復制源代碼,將代碼保存至本地項目文件目錄下,文件后綴改為.html
二、在Python中打開本地html文件
打開並讀取本地文件可使用BeautifulSoup方法直接打開
soup=BeautifulSoup(open('ss.html',encoding='utf-8'),features='html.parser') #features值可為lxml
解析后可以直接使用soup,與請求網頁解析后的使用方法一致
三、使用本地文件爬取資料
1、先爬取主頁的列表資料,其中同義內容使用“@”符號連接
def draw_base_list(doc): lilist=soup.find('div',{'class':'babynames-term-articles'}).findAll('article'); #爬取一級參數 for x in lilist: str1='' count=0 a='@' EnName=x.find('a').text; Mean=x.find('div',{'class':'meaning'}).text; Sou=x.find('div',{'class','related'}).findAll('a') Link=x.find('a').get('href'); for x in Sou: if count!=0:#添加計數器判斷是否為第一個,不是則添加@ str1=str1+a s=str(x) #將x轉換為str類型來添加內容 str1=str1+s count+=1 Source=str1 print(Source);
print(Meaning);
運行后發現Source和Meaning中包含了標簽中的內容,我們使用正則表達式re.sub()方法刪除str中指定內容。查看源代碼可以發現標簽內容只有一個鏈接,可以獲取標簽內的鏈接后再指定刪除。
首先在for循環內給定一個值獲取標簽內的鏈接link=x.get('href'),接着使用sub方法指定刪除link。代碼如下:
link=x.get('href') change2=re.sub(link,'',s)
運行后我們發現str中還存在標簽名,在for循環中指定多余內容刪除:
link=x.get('href') s=str(x) change1=re.sub('<a href="','',s) change2=re.sub(link,'',change1) change3=re.sub('">','',change2) change4=re.sub(' Baby Names','',change3) change5=re.sub('</a>','',change4) change=re.sub(' ','',change5)
最后就能得到想要的信息。
2、再爬取詳細信息
通過def draw_base_list(doc)函數向二級詳情函數傳遞Link參數爬取詳細信息,為避免頻繁訪問主機,我們同樣將詳情頁的源代碼保存至本地並解析。
def draw_detail_list(): str1=‘’ meta="boy" doc=BeautifulSoup(open('nn.html',encoding='utf-8'),features='html.parser') Des=doc.find('div',{'class':'single-babyname-wrapper'}).findAll('p') Gen=doc.find('div',{'class':'entry-meta'}).find('a') #print(Gen) g=str(Gen) for i in Gen: if meta in g: Gender="boy" else: Gender="girl" #print(Gender) for x in Des: #print(x) if x.find('a')==None: #該標簽下有我們不需要的信息,查看源代碼找到信息之間的聯系,發現不需要的信息中都有鏈接 c=str(x) change1=re.sub('<p>','',c) #與一級信息函數一樣刪除指定內容 change2=re.sub('</p>','',change1) change3=re.sub('\t','',change2) change=re.sub('\n','@',change3) str1=str1+change #Description=x.text #print(Description) Description=str1 #print(Description) data={ #將數據存進字典中方便將數據保存至csv文件或數據庫中 'EnName':EnName, 'CnName':'', 'Gender':Gender, 'Meaning':Meaning, 'Description':Description, 'Source':Source, 'Character':'', #網頁中沒有的信息數據列為空 'Celebrity':'', 'WishTag':'' } #print(data)
3、將爬取下來的數據存入csv文件中
def draw_base_list(doc): ...... #爬取一級參數 for x in lilist: ...... for x in Sou: ...... ...... draw_detail_list(Link,EnName,Meaning,Source) #將數據傳給二級信息函數 def draw_detail_list(url,EnName,Meaning,Source): ...... for i in Gen: ...... for x in Des: ...... data={ ...... } write_dictionary_to_csv(data,'Names') #將字典傳給存放數據函數,並給定csv文件名 def write_dictionary_to_csv(dict,filename): file_name='{}.csv'.format(filename) with open(file_name, 'a',encoding='utf-8') as f: file_exists = os.path.isfile(filename) w =csv.DictWriter(f, dict.keys(),delimiter=',', quotechar='"', lineterminator='\n',quoting=csv.QUOTE_ALL, skipinitialspace=True) w.writerow(dict)
打開文件后發現沒有文件頭,為避免重復寫入文件頭,判斷文件是否為空,若為空則寫入文件頭:
#防止每次循環重復寫入列頭 if os.path.getsize(file_name)==0 : #通過文件大小判斷文件是否為空,為0說明是空文件 w.writeheader()
再次運行后文件頭正常寫入文件中。
4、訪問主機,完成信息爬取
確定代碼正確沒有錯誤后就可以將打開本地文件的代碼改成訪問網頁,最后完成數據的爬取。