实战项目四:爬取911网站
這是我在某個項目寫的一份爬蟲代碼,今天將它整理一下分享給大家,僅供參考學習,請勿用作其他用途。
需要爬取的東西
我爬取的是 https://myingwenming.911cha.com 網站,采集的是網站中的中文音譯、名字性別、來源語種、名字寓意、名字印象、名字含義6個數據。我分別設置namesChineseTransliteration、namesGender、namesFromLanguage、namesMoral、namesImpression、namesMeaning等6個字段來存放相應的數據。
防反扒措施
在這防反扒這一塊我選擇每發送一次requests請求更換一個User-Agent與IP。User-Agent的更換我依靠第三方庫fake_useragent來完成,在每次發送requests請求前通過{'User-Agent':str(UserAgent().random)}語句來獲取一個隨機User-Agent。關于代理IP這塊我則是事先準備好IP存放到IP.txt文件中,每一次發送requests前從該文件中隨機獲取一個IP用于本次請求。
def get_ip_list():'''讀取IP.txt中的數據'''f=open('IP.txt','r')ip_list=f.readlines()f.close()return ip_listdef get_random_ip(ip_list):'''從IP列表中獲取隨機IP'''proxy_ip = random.choice(ip_list)proxy_ip=proxy_ip.strip('\n')proxies = {'http': proxy_ip}return proxies關于requests請求
我這里的requests請求供包含url、proxies、headers、timeout、verify五個參數,在每一次發送請求前更換新的proxies,headers并在超時處理,若請求時間超過10秒則中斷本次請求,設置verify=False則會忽略對網頁證書的驗證。
在我遇到的反扒系統中有這樣一種,拿出來和大家分享。對方識別到你的爬蟲在網站上爬行時,不會阻止它的爬取行為而是讓其陷入一種死循環轉態,表現的形式是:本報錯同時也不會返回任何數據。在requests請求中加上一個超時設置就可以很好避開該反扒措施。
關于網頁解析
在網頁解析這塊我選擇的是Python解析庫BeautifulSoup4與解析器lxml,在定位方面我選擇的是find()與find_all(),find()返回的是單個結點,find_all()返回結點列表,在提取文本信息中我這里使用的是get_text()。
首先定位到<div class="pp">,其次是div下的p標簽,最后分別存入對應的字段當中。
soup = BeautifulSoup(r.text, 'lxml') body = soup.find("div", class_="pp") contents = body.find_all('p')完整代碼
from fake_useragent import UserAgent from bs4 import BeautifulSoup import pandas as pd import requests,csv,time,randomdef get_ip_list():'''讀取IP.txt中的數據'''f=open('IP.txt','r')ip_list=f.readlines()f.close()return ip_listdef get_random_ip(ip_list):'''從IP列表中獲取隨機IP'''proxy_ip = random.choice(ip_list)proxy_ip=proxy_ip.strip('\n')proxies = {'http': proxy_ip}return proxiesdef parsePage(url,ip_list):'''爬取網頁并返回所需信息以及狀態碼'''headers= {'User-Agent':str(UserAgent().random)}proxies = get_random_ip(ip_list)try:#verify設置為False,Requests也能忽略對SSL證書的驗證。r = requests.get(url, proxies=proxies, headers=headers, timeout=10,verify=False)except:print('運行錯誤,程序暫停20秒')time.sleep(20)headers= {'User-Agent':str(UserAgent().random)}proxies = get_random_ip(ip_list)r = requests.get(url, proxies=proxies, headers=headers, timeout=10, verify=False)#狀態碼status_code為200代表爬取成功,為404則為未爬取到相關信息if r.status_code == 200:soup = BeautifulSoup(r.text, 'lxml')body = soup.find("div", class_="pp")contents = body.find_all('p')return r.status_code, contentselse:return r.status_code, Nonedef getDict(contents):namesChineseTransliteration = [] #中文音譯namesGender = [] #名字性別namesFromLanguage = [] #來源語種namesMoral = [] #名字寓意namesImpression = [] #名字印象namesMeaning = [] #名字含義namesChineseTransliteration.append(contents[1].get_text()[4:])namesGender.append(contents[-5].get_text()[4:])namesFromLanguage.append(contents[-4].get_text()[4:])namesMoral.append(contents[-3].get_text()[4:]) namesImpression.append(contents[-2].get_text()[4:])namesMeaning.append(contents[-1].get_text()[4:])str_row=namesChineseTransliteration+namesGender+namesFromLanguage+namesMoral+namesImpression+namesMeaningreturn str_rowdef write_file(filePath, row):with open(filePath,'a+',encoding='utf-8',newline='') as csvfile:spanreader = csv.writer(csvfile,delimiter='|',quoting=csv.QUOTE_MINIMAL)spanreader.writerow(row)if __name__ == "__main__":names = pd.read_csv("name_data.csv")['name'] #獲取需要爬取文件的名字base_url = "https://myingwenming.911cha.com/"ip_list = get_ip_list()for name in names:url = base_url + name + ".html"status_code, contents = parsePage(url,ip_list)print("{}檢索完成".format(name), "狀態碼為:{}".format(status_code))#狀態碼為200爬取成功,狀態碼為404爬取失敗if status_code == 200:str_row = getDict(contents)row = ["{}".format(name)] + str_rowwrite_file("new.csv",row)else:continue有不明的地方在下方留言,我看到后會盡快回復的
歡迎進行我的博客導航:【全站式導航】
我的專欄:【機器學習100天】、【K童鞋的爬蟲筆記】
總結
以上是生活随笔為你收集整理的实战项目四:爬取911网站的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实战项目一:爬取西刺代理(获取代理IP)
- 下一篇: 实战项目五:抓取简书文章信息