爬蟲學習之路
阿新 • • 發佈:2019-01-08
高階篇
學會用框架,能站在巨人肩膀上的人,能力往往都不會太差。
這裡我們學習的是PySpider
PySpider環境搭建 (Windows)
pip install pyspider
安裝pyspider (前面python 已經安裝了2.7)
下載phantomjs-2.1.1-windows
加入環境變數,動態載入js會用到
我們使用mysql儲存
如果不需要儲存到mysql, 這步可以直接跳過
安裝mysql,Navicat Premium(db管理工具)
執行 cmd -> pyspider all
到這裡環境就搭建完成了
Pyspider的基礎
先了解下pyspider的功能:
Pyspider入門實踐 - 定時爬取下載量
下面我們從豌豆莢,百度手機助手,應用寶爬出某個應用的下載量。
code說明:
- init方法是初始化方法,裡面放了一些url資料,時間等。
- on_start是入口,相當於main方法
- @every(minutes=24 * 60) # 每天執行一次
- @every(minutes=1) # 每min執行一次, 這個一般除錯時用,方便實時檢視情況
- 頁面解析的三個方法: index_wdjpage, index_baidupage,index_yingyongbaopage
- @config(age=60) # 有效期1min 一分鐘後才會過期。真正抓的頻率是 on_start的@ every + 這裡的age。即2分鐘才會run一次index_wdjpage
- @config(priority=3) # priority設定優先順序,數字越高代表最先run到
Code例項
#!/usr/bin/env python # -*- encoding: utf-8 -*- # Created on 2017-11-29 16:32:33 # Project: ZenTalk_Download from pyspider.libs.base_handler import * import sys reload(sys) sys.setdefaultencoding('utf-8') import uniout import re import time class Handler(BaseHandler): crawl_config = { } def __init__(self): self.wdjurl = 'http://www.wandoujia.com/apps/com.asus.cnzentalk' self.baiduurl = 'http://shouji.baidu.com/software/11306355.html' self.yingyongbaourl = 'http://sj.qq.com/myapp/detail.htm?apkName=com.asus.cnzentalk' self.tool = Tool() self.time = self.tool.getCurrentIntTime() FILE_NAME = 'zentalk_download.txt' #@every(minutes=24 * 60) # 每天執行一次 @every(minutes=1) # 每1min執行一次 def on_start(self): self.crawl(self.wdjurl, callback=self.index_wdjpage, fetch_type='js') self.crawl(self.baiduurl, callback=self.index_baidupage, fetch_type='js') self.crawl(self.yingyongbaourl, callback=self.index_yingyongbaopage, fetch_type='js') @config(age=60) # 有效期1min @config(priority=3) def index_wdjpage(self, response): raw_download = response.doc('[itemprop="interactionCount"]').text() download = self.tool.getCount(raw_download) # write to file self.writeToFile(download, '豌豆莢') @config(age=60) # 有效期1min @config(priority=2) def index_baidupage(self, response): raw_download = response.doc('.yui3-g .download-num').text() download = self.tool.getCount(re.split(':', raw_download)[1]) # write to file self.writeToFile(download, '百度手機助手') @config(age=60) # 有效期1min @config(priority=1) def index_yingyongbaopage(self, response): raw_download = response.doc('.det-ins-num').text()[:-2] download = self.tool.getCount(raw_download) # write to file self.writeToFile(download, '應用寶' ) def writeToFile(self, download, platform, append=True): if append : f = open(self.FILE_NAME, 'a') f.write(platform + ": " + str(download) + '\n') else: f = open(self.FILE_NAME, 'w') f.write("\n------ time: " + self.tool.getCurrentTime() + "," + str(self.tool.getCurrentIntTime()) + " ------------------\n") f.write(platform + ": " + str(download) + '\n') f.close() # 工具類 class Tool: # 將超連結廣告剔除 removeADLink = re.compile('<div class="link_layer.*?</div>') # 去除img標籤,1-7位空格, removeImg = re.compile('<img.*?>| {1,7}| ') # 刪除超連結標籤 removeAddr = re.compile('<a.*?>|</a>') # 把換行的標籤換為\n replaceLine = re.compile('<tr>|<div>|</div>|</p>') # 將表格製表<td>替換為\t replaceTD = re.compile('<td>') # 將換行符或雙換行符替換為\n replaceBR = re.compile('<br><br>|<br>') # 將其餘標籤剔除 removeExtraTag = re.compile('<.*?>') # 將多行空行刪除 removeNoneLine = re.compile('\n+') def replace(self, x): x = re.sub(self.removeADLink, "", x) x = re.sub(self.removeImg, "", x) x = re.sub(self.removeAddr, "", x) x = re.sub(self.replaceLine, "\n", x) x = re.sub(self.replaceTD, "\t", x) x = re.sub(self.replaceBR, "\n", x) x = re.sub(self.removeExtraTag, "", x) x = re.sub(self.removeNoneLine, "\n", x) # strip()將前後多餘內容刪除 return x.strip() # it support convert string include unit to count # such as 6000,60.2萬,1億 def getCount(self, x): x = self.replace(x) if (self.isFloat(x) or str.isdigit(str(x))): return x else: num = re.findall("\d+\.?\d*", x)[0] unit = re.sub(num, "", x) unit_number = 1 if (unit == "萬"): unit_number = 10000 elif (unit == "億"): unit_number =100000000 return float(num) * unit_number def isFloat(self, number): try: num = float(number) return True except ValueError: return False # 獲取當前時間 def getCurrentTime(self): return time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime(time.time())) # 獲取當前時間 unix 時間戳 def getCurrentIntTime(self): return (int)(time.mktime(time.localtime(time.time())))
Pyspider的Tip
- Pyspider的建立的專案都放在下面的位置,以db的形式儲存