Selenium模塊是一套完整的Web應用程序測試系統,它包含了測試的錄製(SeleniumIDE)、編寫及運行(Selenium Remote Control)和測試的並行處理(Selenimu Grid); python
那麼咱們在編寫網絡爬蟲時主要用來了Selenium 的Webdriver 模塊 ;android
在以上的列表中android 和blackberry 是移動端的瀏覽器,能夠先去掉,common support 也能夠先去掉,剩下的除去Phantomjs 則都是常見的瀏覽器,PhantomJS 是一個基於WebKit 的服務端的JS API,它全面支持web 而不須要瀏覽器支持,其快速、原生支持各類web 標準;沒有界面,則意味着開銷小,同時速度也快,那麼咱們在爬取JS才能返回數據的網站時,沒有比selenium和phantomjs 更適合的組合 了;web
下載PhantomJS :http://phantomjs.org/windows
我使用的是windows 環境,那麼下載完壓縮包後,直接解壓,將PhantomJS.exe 放到python 的目錄中就能夠 了瀏覽器
交互式的小例子我就寫了,直接上一個實例代碼,也能夠將實例中的解析網頁源碼部分在交互式環境中敲一遍,體驗一下;網絡
#!/usr/bin/env python #coding:utf-8 """用selenium&PhantomJS 完成的網絡爬蟲,最適合使用的情形是爬取有JS的網站,可是用來爬取其餘網站一樣給力""" from selenium import webdriver from myLog import MyLog as mylog import sys reload(sys) sys.setdefaultencoding('utf-8') class Item(object): #用於存儲代理的屬性 ip = None port = None anonymouns = None type = None support = None local = None speed = None class GetProxy(object): def __init__(self): self.starturl = "http://www.kuaidaili.com/free/inha/" #目標網址 self.log = mylog() #二次封裝的日誌模塊 self.urls = self.getUrls() self.proxyList = self.getProxyList(self.urls) self.fileName = 'proxy.txt' self.saveFile(self.fileName,self.proxyList) def getUrls(self): ##生成目標頁面代理的網頁頁面URL urls = [] for i in xrange(1,3): url = self.starturl + str(i) urls.append(url) self.log.info('get URL %s to urls' %url) return urls def getProxyList(self,urls): ##分析網頁源代碼 browser = webdriver.PhantomJS() ## 使用selenium&PhantomJS proxyList = [] for url in urls: browser.get(url) #打開網頁 browser.implicitly_wait(5) #智能等待加載JS模塊 elements = browser.find_elements_by_xpath('//tbody/tr') #使用xpath來解析網頁源碼 for element in elements: item = Item() item.ip = element.find_element_by_xpath('./td[1]').text item.port = element.find_element_by_xpath('./td[2]').text item.anonymouns = element.find_element_by_xpath('./td[3]').text item.type = element.find_element_by_xpath('./td[4]').text item.support = element.find_element_by_xpath('./td[5]').text item.local = element.find_element_by_xpath('./td[6]').text item.speed = element.find_element_by_xpath('./td[7]').text proxyList.append(item) self.log.info('add proxy %s: %s to list'%(item.ip,item.port)) browser.quit() #瀏覽器的退出 return proxyList def saveFile(self,fileName,proxyList): #生成文件 self.log.info('add all proxy to %s'%self.fileName) with open(fileName,'w') as fp: for item in proxyList: # print item.ip fp.write(item.ip+'\t') fp.write(item.port + '\t') fp.write(item.anonymouns + '\t') fp.write(item.type + '\t') fp.write(item.support + '\t') fp.write(item.local + '\t') fp.write(item.speed + '\n') self.log.info('write %s:%s to file successfuly......'%(item.ip,item.port)) if __name__ == "__main__": USE = GetProxy()
因爲這幾回在使用本身二次封裝的myLog模塊並未加註釋,這次補上,將內置logging模塊再次封裝,增長了獲取用戶名,多路徑日誌輸出;架構
#!/usr/bin/env python #coding:utf-8 #date 2017_11_30 #author chenjisheng import logging import getpass class MyLog(object): '''此類用來封裝已有logging類,方便本身使用''' def __init__(self): self.user = getpass.getuser() #獲取使用的用戶 self.logger = logging.getLogger(self.user) #初始化一個logger 對象 self.logger.setLevel(logging.DEBUG) #設置logger 的日誌級別 self.logfile = "progress_log.log" #設置日誌保存的文件 self.formates = logging.Formatter( "[%(asctime)s] - USERNAME:[%(name)s] - [%(levelname)s] - %(message)s" ) #設置日誌的格式 self.Hand = logging.FileHandler(self.logfile) #設置日誌的輸出爲文件 self.Hand.setFormatter(self.formates) #使用日誌的格式 self.Hand.setLevel(logging.ERROR) #設置輸出爲文件的日誌級別 self.HandStream = logging.StreamHandler() #設置日誌的輸出格式爲console self.HandStream.setFormatter(self.formates) #使用日誌的格式 self.HandStream.setLevel(logging.DEBUG) #設置輸出爲窗口的日誌級別 self.logger.addHandler(self.HandStream) #增長日誌的輸出對象給logger(負責發送消息) self.logger.addHandler(self.Hand) #增長日誌的輸出對象給logger def debug(self,messages): self.logger.debug(messages) def info(self,messages): self.logger.info(messages) def warning(self,messages): self.logger.warning(messages) def error(self,messages): self.logger.error(messages) def critical(self,messages): self.logger.critical(messages) if __name__ == "__main__": mylog = MyLog() mylog.debug("I'm debug") mylog.info("I'm info") mylog.warning("I'm warning") mylog.error("I'm error ") mylog.critical("I'm critical")
代碼學習都是在不斷練習中成長,下一篇將上傳一個簡易的爬蟲架構。app