簡單爬蟲框架實現
目錄html
框架流程 調度器
url管理器 網頁下載器 網頁解析器 數據處理器 具體演示效果
框架流程
調度器
#導入模塊 import Url_Manager import parser_html import html_output import download class SpiderMain(object): def __init__(self): #實例化:url管理器,網頁下載器,網頁解析器,數據輸出 self.urls=Url_Manager.UrlManager() self.parser=parser_html.Htmlparser() self.download = download.download() self.outputer=html_output.HtmlOutputer() def craw(self,root_url): count=1 #向列表裏面添加新的單個url self.urls.add_new_url(root_url) #判斷待爬取的url列表裏面有沒有新的url while self.urls.has_new_url(): try: #若是待爬取的url列表不爲空,則取一個url出來 new_url=self.urls.get_new_url() print('craw %d:%s' % (count,new_url)) #下載網頁 html_cont=self.download.download(new_url) #解析網頁 #解析得到兩個數據:新的url,以及咱們要獲取的數據 new_urls,new_data=self.parser.parse(new_url,html_cont) #獲取的url添加到待爬取的url列表 self.urls.add_new_urls(new_urls) #保存數據 self.outputer.collect_data(new_data) #若是下載的url頁面達到50個,結束當前循環 if count ==50: break count=count+1 except: print('craw failed') #輸出數據 self.outputer.output_html() if __name__ == '__main__':
#開始爬取的url url = "http://www.dili360.com/gallery/" root_url=url #實例化 obj_spider=SpiderMain() obj_spider.craw(root_url)
url管理器
#url管理器須要四個方法: #add_new_url:向管理器添加單個url #add_new_url:向管理器添加批量的url #has_new_url:判斷管理器裏面是否有新的在爬取的url #get_new_url:在管理器中獲取一個正在爬取的url #url管理器須要維護兩個列表:待爬取的url,已經爬取的url class UrlManager(object): def __init__(self): #待爬取的url列表 self.new_urls=set() #已經爬取的url列表 self.old_urls=set() #向管理器添加單個url def add_new_url(self,url): #首先判斷url是否爲空 if url is None: return #若是這個url既不在待爬取的url裏面也沒有在已經爬取的url裏面,則說明這是一個新url if url not in self.new_urls and url not in self.old_urls: self.new_urls.add(url) # 向管理器添加批量的url def add_new_urls(self,urls): if urls is None or len(urls) ==0: return for url in urls: self.add_new_url(url) #判斷管理器裏面是否有新的在爬取的url def has_new_url(self): return len(self.new_urls) != 0 # 獲取一個正在爬取的url def get_new_url(self): new_url = self.new_urls.pop() self.old_urls.add(new_url) return new_url
網頁下載器
import requests class download(object): def download(self,url): if url is None: return None else: response = requests.get(url) if response.status_code !=200: return None return response.text
網頁解析器
from urllib.parse import urljoin from bs4 import BeautifulSoup class Htmlparser(object): def _get_new_urls(self,page_url,soup): new_urls = set()
#這裏能夠加上正則表達式,對url進行過濾 links=soup.find_all('a') for link in links: #補全url,添加到列表裏面 new_url=link['href'] new_full_url=urljoin(page_url,new_url) new_urls.add(new_full_url) return new_urls def _get_new_data(self,page_url,soup): #解析數據,由用戶來編寫 new_datas=set() imgs=soup.find_all('img') for img in imgs: new_data=img['src'] new_full_data=new_data new_datas.add(new_full_data) return new_datas #須要解析出新的url和數據 def parse(self,page_url,html_cont): if page_url is None or html_cont is None: return soup=BeautifulSoup(html_cont,'html.parser') #調用兩個本地方法:解析新的url以及解析數據 new_urls=self._get_new_urls(page_url,soup) new_data = self._get_new_data(page_url,soup) return new_urls,new_data # 報錯: # UserWarning: You provided Unicode markup but also provided a value for from_encoding. Your from_encoding will be ignored. # 解決方法: # soup = BeautifulSoup(html_doc,"html.parser") # 這一句中刪除【from_encoding="utf-8"】 # 緣由: # python3 缺省的編碼是unicode, 再在from_encoding設置爲utf8, 會被忽視掉,去掉【from_encoding="utf-8"】這一個好了
數據處理器
使用文檔保存文本信息python
使用文件保存圖片,視頻文件等,可進行擴展正則表達式
class HtmlOutputer(object): def __init__(self): self.datas=[] def collect_data(self,data): if data is None: return self.datas.append(data) def output_html(self): fout=open('output','a+') for data in self.datas: for da in data: fout.write(str(da)+'\n') fout.close()
具體演示效果
演示url:http://www.dili360.com/gallery/app
演示過程:框架
數據處理:ide