在慕課網學習並建立了一個簡單的爬蟲包,爬取百度百科相關詞條信息html
程序中會用到第三方解析包(BeautifulSoup4),Windows環境下安裝命令:pip install BeautifulSoup4node
一、新建包python
二、新建相關類文件,其中包含有:git
index.py,包入口類文件;github
url_manager.py,url管理器類文件,主要管理待爬url列表和已爬url列表,避免重複或循環爬取;app
html_downloader.py,html內容下載器類文件,下載接收url內容到本地;函數
html_parser.py,html內容解析器類文件,解析url內容,取出需求數據;學習
html_outputer.py,爬取內容收集輸出器類文件,主要收集各url中需求數據並輸出;url
三、貼(代碼註釋好詳細的。。。)code
index.py
# !/usr/bin/env python # -*- coding: UTF-8 -*- # addUser: Gao # addTime: 2018-01-31 22:22 # description: 入口 from Crawler import url_manager, html_downloader, html_parser, html_outputer class Index(object): # 構造函數 初始化各管理器 def __init__(self): # url管理器 self.urls = url_manager.UrlManager() # html下載管理器 self.downloader = html_downloader.HtmlDownloader() # html解析管理器 self.parser = html_parser.HtmlParser() # 數據收集管理器 self.outputer = html_outputer.HtmlOutputer() # 爬蟲 def craw(self, url): count = 1 # 將初始地址加入url管理器 self.urls.add_new_url(url) # 判斷是否存在新的url地址 存在時執行爬取程序 while self.urls.has_new_url(): try: # 獲取新的url地址 new_url = self.urls.get_new_url() print 'craw %d : %s' % (count, new_url) # 獲取url地址內容 html_cont = self.downloader.download(new_url) # 解析url內容 news_url, new_data = self.parser.parse(new_url, html_cont) # 將解析獲得的url地址列表批量加入url管理器中 self.urls.add_new_urls(news_url) # 收集數據 self.outputer.collect_data(new_data) if count == 100: break count += 1 # 異常處理 except: print 'craw failed' # 輸出收集的數據 self.outputer.output_html() if __name__ == '__main__': # 初始url地址 initial_url = 'https://baike.baidu.com/item/%E5%94%90%E8%AF%97%E4%B8%89%E7%99%BE%E9%A6%96/18677' # 建立對象 Obj = Index() # 調用爬蟲 Obj.craw(initial_url)
url_manager.py
# !/usr/bin/env python # -*- coding: UTF-8 -*- # addUser: Gao # addTime: 2018-01-31 22:22 # description: url管理器 class UrlManager(object): # 構造函數 初始化url列表 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是否已存在或是否已爬 if url not in self.new_urls and url not in self.old_urls: # 添加到待爬url列表 self.new_urls.add(url) # 批量添加url def add_new_urls(self, urls): # 判斷urls是否爲空 if urls is None or len(urls)==0: return # 循環執行添加單個url 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): # 取出待爬url列表中的一個url new_url = self.new_urls.pop() # 將取出的url添加到已爬url列表中 self.old_urls.add(new_url) # 返回取出的url return new_url
html_downloader.py
# !/usr/bin/env python # -*- coding: UTF-8 -*- # addUser: Gao # addTime: 2018-01-31 22:22 # description: html下載器 import urllib2 class HtmlDownloader(object): # 下載url內容 def download(self, url): # 判斷url是否爲空 if url is None: return None # 下載url內容 response = urllib2.urlopen(url) # 判斷url地址請求結果 if response.getcode() != 200: return None # 返回url加載內容 return response.read()
html_parser.py
# !/usr/bin/env python # -*- coding: UTF-8 -*- # addUser: Gao # addTime: 2018-01-31 22:22 # description: html解析器 import re, urlparse from bs4 import BeautifulSoup class HtmlParser(object): # 解析url的內容 def parse(self, url, html_cont): # 參數爲空判斷 if url is None or html_cont is None: return # 建立解析對象 soup = BeautifulSoup(html_cont, 'html.parser', from_encoding='utf-8') # 獲取新的待爬url列表 new_urls = self._get_new_urls(url, soup) # 獲取需求數據 new_data = self._get_new_data(url, soup) # 返回url列表和數據 return new_urls, new_data # 獲取url內容中的詞條url列表 def _get_new_urls(self, url, soup): # 初始化url列表 new_urls = set() # 獲取頁面全部詞條a標籤列表 links = soup.find_all('a', href=re.compile(r'^/item/')) for link in links: new_url = link['href'] # 獲取a標籤中href屬性值 full_url = urlparse.urljoin(url, new_url) # 拼接完整url地址 new_urls.add(full_url) # 將完整的url添加到url列表中 # 返回url列表 return new_urls # 獲取url內容中的需求數據 def _get_new_data(self, url, soup): # 初始化數據詞典 data = {} title_node = soup.find('dd', class_='lemmaWgt-lemmaTitle-title').find('h1') # 獲取標題標籤 data['title'] = title_node.get_text() # 獲取標題文本 summary_node = soup.find('div', class_='lemma-summary') # 獲取詞條概要標籤 data['summary'] = summary_node.get_text() # 獲取詞條概要文本 data['url'] = url # 詞條對應url地址 # 返回數據 return data
html_outputer.py
# !/usr/bin/env python # -*- coding: UTF-8 -*- # addUser: Gao # addTime: 2018-01-31 22:22 # description: html輸出器 class HtmlOutputer(object): # 構造函數 初始化收集的數據 def __init__(self): self.Data = [] # 收集數據 def collect_data(self, data): # 數據爲空判斷 if data is None: return # 添加數據到列表 self.Data.append(data) # 輸出收集的數據 def output_html(self): # 打開文件 out_file = open('output.html', 'w') out_file.write('<html><body><table>') for data in self.Data: out_file.write('<tr>') out_file.write('<td>%s</td>' % data['title'].encode('utf-8')) out_file.write('<td>%s</td>' % data['url'].encode('utf-8')) out_file.write('<td>%s</td>' % data['summary'].encode('utf-8')) out_file.write('</tr>') out_file.write('</table></body></html>') # 關閉文件 out_file.close()
四、運行和調用
代碼擼完了,確定要看看它是否能使用啦
在包中,選擇入口類文件(index.py),右擊執行Run命令;
在包外,即調用該爬蟲包,首先要引入該包入口類文件(index.py),再實例化對象,最後調用爬取方法,固然還得執行Run命令啦。