全自動監控網站關鍵字排名(Python實現)

來源:互聯網
上載者:User

仲介交易 SEO診斷 淘寶客 雲主機 技術大廳

從這篇文章開始不打算再花費大量精力去寫程式本身的知識,畢竟是各類書籍上有的內容。 其餘主要需要學習的是內建函數的使用,和一些模組的使用方式,尤其是pycurl, re, threading這些需要慢慢熟悉起來。

若在學習中有不解的地方,在文章評論中可以提出,如果有空會盡力幫忙解答。

程式需求

對於稍大的一個網站,往往會有許多關鍵字需要每隔一個週期監控它們的排名,以分析SEO效果的好壞,及判斷百度Google的動向等等。

有一個關鍵在於資料的收集全自動與否的問題。 若經常用Google Analytics分析資料的話應該會感覺到,資料分析的需求是多種多樣的,只有事先已經有了完善的各個維度的資料以後,才能隨著最初的想法進行分析,而不會為數據的匱乏所局限。 像Google Analytics這樣出色的工具完全自動的將這些資料收集了起來,才給SEO對於流量的多樣化分析打下了基礎。 同樣的,如果想分析的時候更自由的話,就需要記錄盡多種類的歷史資料,如果這些作為每日工作,那將耗時非常長,所以自動化的收集就體現出了其重要性。

現有的監控排名主要解決方案是使用商務軟體Rank Tracker,但它也有些不是很理想的地方。 比如對於幾乎所有既有軟體都存在的問題,功能不靈活。 另外它最大的弊端之一在於它一定要找個具有圖形介面的系統運行(因為它是JAVA實現的,有多作業系統版本,所以不一定是Windows)。

對於DIY的Python腳本,在Linux系統裡面可以將其放到crontab中(系統級計畫任務),全自動的定時運行收集原始資料。 然後在需要的時候,再用另外的腳本來處理原始資料,進行各個維度的分析。 所需的一般情況下為:Linux系統的低配置VPS一台,總共不超過100行的Python代碼(Windows也能實現這些,但相對比較麻煩)。

然後再來分析更具體的需求。 此處我總結了一些原則:

1. 除非資料量大到會對硬碟帶來壓力(比如每日數G的日誌的分析等),不然把能想到的盡多的資料都記錄下來。 因為分析的需求是多變的,資料若全面即可有備無患。

2. 同上,除非資料量極大,不然務必把歷史資料全部保存下來。 在大資料量的時候,也需要按實際情況保存一定時間區間的資料(打個比方,前3年每月保存一副本,當年每週保存一副本)。 歷史資料的對比在很多時候的意義非常大。

3. 當資料非常單一的時候,使用txt按行保存;當資料比較簡單的時候,使用csv按行列儲存;當資料比較複雜的時候,可以考慮使用MongoDB等key-value型NoSQL儲存;再複雜的時候, 使用MySQL之類的關係性資料庫儲存。 但這些不是絕對的,還是要看實際情況而定。

對於目前的需求,因為是要監控關鍵字排名趨勢,所以一般最多監控幾千個關鍵字就夠了。 或許網站比較大,想瞭解數十萬的關鍵字的排名,但對於瞭解排名趨勢的情況下,沒必要全部查詢,隨機選取其中一小部分作為樣本就可以了。

因為最多幾千個關鍵字,所以最好每天記錄一次它們的排名資料(保證穩定的情況下,對於單IP,Google每天可以查詢5000+詞,百度則可以查詢數萬的詞)。 而且資料本身,主要為關鍵字、排名、著陸頁URL這幾項,檔體積很小,所以每天都保存一份資料。

資料的儲存方式上,此時一般建議選擇csv。 它和Excel表格(xls)在資料的儲存方式上是一模一樣的。

代碼實現

這些代碼需要以下運行環境:

Linux作業系統

Python的協力廠商模組pycurl

Python下載網頁的最簡單方式是:

import urllib2

print urllib2.urlopen('HTTP://***.com/').read()

但urllib2模組本身功能雖然還行,卻仍離pycurl模組有較大距離。 且在做稍微複雜一些的操作時,pycurl模組使用起來比urllib2模組方便很多。 pycurl是必須要熟練運用的模組之一,但也因為它上手可能會讓人有點頭疼,這裡我自己寫了一個模組,以此即可方便的使用它:

from pycurl import *

import StringIO, time, random

def curl(url, retry=False, delay=1, **kwargs):

'''Basic usage: curl('HTTP://www.xxx.com/'), will download the url.

If set `retry` to True, when network error, it will retry automatically.

`delay` set the seconds to delay between every retry.

**kwargs can be curl params. For example:

curl(url, FOLLOWLOCATION=False, USERAGENT='Firefox')

'''

useragent_list = [

'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6',

'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',

'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)',

'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)',

'Opera/9.20 (Windows NT 6.0; U; en)',

'Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.1; .NET CLR 1.1.4322)',

'Opera/9.00 (Windows NT 5.1; U; en)',

'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.50',

'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.0',

'Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.02 [en]',

'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20060127 Netscape/8.1',

]

size = len(useragent_list)

useragent = useragent_list[random.randint(0, size-1)]

s = StringIO.StringIO()

c = Curl()

c.setopt(NOSIGNAL, True)

c.setopt(FOLLOWLOCATION, True)

c.setopt(MAXREDIRS, 5)

c.setopt(TIMEOUT, 120)

for key in kwargs:

c.setopt(locals()[key], kwargs[key])

c.setopt(URL, url)

c.setopt(WRITEFUNCTION, s.write)

if ‘USERAGENT’ not in kwargs:

c.setopt(USERAGENT, useragent)

if ‘REFERER’ not in kwargs:

c.setopt(REFERER, url)

while 1:

try:

c.perform()

break

except:

if retry:

time.sleep(delay)

else:

return False

return s.getvalue()

對於簡單的採集裡面需要用到的下載功能,已經被整合在了這個模組之中。 如User-agent輪換、自動301/302跳轉等、使用當前URL作為REFERER的有些取巧的方法等。 這個模組的代碼可以日後再慢慢理解,現在只要知道它的用法即可。

首先到放置Python腳本的目錄,將前面一段代碼保存為curl.py,然後在同一目錄下創建一個新檔,輸入以下測試代碼:

# -*- coding:utf-8 -*-

import curl

print curl.curl('HTTP://g.cn/') #這樣即下載了一個網頁

#以下是比較保險的下載方式,因為各種原因,就算總體很穩定的網站也偶爾會出現網頁暫時無法打開的情況

#當網頁下載出錯時,如果retry為True,則會不斷重試,直到下載完網頁

#delay則指定了幾次重試之間的時間間隔,以秒為單位

print curl.curl('HTTP://g.cn/', retry=True, delay=1)

#以下用到了一些Curl的參數,詳細說明可見:HTTP://curl.haxx.se/libcurl/c/curl_easy_setopt.html

print curl.curl('HTTP://g.cn/', FOLLOWLOCATION=False, COOKIE='mycookie')#p#副標題#e#

這個模組會在以後幾乎每個腳本裡面都用到,所以這些基礎用法務必牢記。 接下來是監控網站關鍵字排名的正式代碼:

cron.py

# -*- coding:utf-8 -*-

#載入模組,此處大致按功能劃分行,是為了能夠更方便理解代碼

import sys, os, random, time, datetime

import urllib, re

import curl

#sys.argv是系統參數,1:3切片意味著讀取參數2,3,分別賦值給兩個變數

site, file_keyword = sys.argv[1:3]

keywords = [] #先將keywords聲明初始為清單型變數

#反覆運算檔,每次讀取一行文字

for line in open(file_keyword):

line = line.rstrip() #將行尾的空白字元去掉,一般行尾會有分行符號等

if line:#判斷該行是否是空白行,也可更標準的寫作if len(line)! =0:

keywords.append(line) #將讀取到的文字加入到keywords清單中

#獲取UTC時間,之所以使用UTC時間是為了避免時區問題帶來的未知麻煩

#北京時間是UTC+8,如該日UTC時間01:00相當於北京時間09:00

now = datetime.datetime.utcnow()

#將UTC時間格式化,變成如1970-01-01的格式

date = datetime.datetime.strftime(now, '%Y-%m-%d')

#嘗試創建資料夾,如果資料夾已創建則跳過

try:

os.mkdir('/home/rank/')

except:

pass

#打開輸出資料的檔,以當日的日期命名它

f = open('/home/rank/%s.csv' % date, 'w')

for keyword in keywords:

#因為關鍵字可能是非ASCII字元集的,所以需要編碼

encoded_keyword = urllib.quote_plus(keyword)

#下載SERP並提取連結

url = 'HTTP://www.baidu.com/s?wd=%s&rn=100' % encoded_keyword

#下載SERP,如果出現驗證碼即延時10分鐘並重試

while 1:

html = curl.curl(url, retry=True, delay=60)

if '<img src="HTTP://verify.baidu.com/cgi-bin/' in html:

except:

f.write('%s\t%d\t%s\n' % (keyword, -1, '-'))

continue

#如果在前100名找到網站,則find=True

find = False

#在SERP上面的URL中,尋找網站並確定排名

for pos, url in enumerate(urls, 1):

if site in url:

f.write('%s\t%d\t%s\n' % (keyword, pos, url))

find = True

break

#如果前100名沒有找到網站

if not find: #更標準的寫法是if find==False:

f.write('%s\t%d\t%s\n' % (keyword, -1, '-'))

delay = random.randint(1,2) #隨機設定延時時間為1秒或2秒

time.sleep(delay) #等待x秒以後繼續查詢下一個詞的排名

這段代碼即可監控排名並收集資料。 它的使用命令如:python cron.py semwatch.org keywords.txt

在運行之前,先要把關鍵詞按行分隔,保存成txt檔,並在運行參數中讓腳本去讀取它。 每次運行之後,會在/home/rank/資料夾下,創建一個類似1970-01-01.csv這樣檔案名的檔,保存著當日的關鍵字排名情況。

為了讓排名查詢能自動化,可以將腳本設置為Linux的計畫任務。 在終端敲入:crontab -e,即可進入對於計畫任務的編輯(它也使用一段腳本控制,而非Windows是圖形介面)。 為此必須要對VIM編輯器有最基礎的瞭解,至少要能把字打上去並保存,可參考:HTTP://ooxx.me/basic-vi.orz

在crontab輸入並保存:00 05 * * * python cron.py semwatch.org keywords.txt

此處為了簡化一些Linux的環境變數的問題,需要將cron.py, curl.py, keywords.txt三個檔,都放到~資料夾下。 crontab的預設執行路徑便是~。

前面一段命令的意思是在每日05:00自動執行腳本。 當然需要電腦是處於開機的狀態,也因此推薦使用一般不會關機的VPS來做這些監控類任務。 此外需要注意的是系統的時間,VPS上面的時區可能和本地不同,可以在終端下使用date命令來確認。

至此日常排名資料的收集已經完成了,但光收集肯定不行,還需要分析。 分析可以是各個角度的,這裡以最常用的舉例,分析網站關鍵字排名整體上升或下降的趨勢。 代碼很簡單:

analyse.py

# -*- coding:utf-8 -*-

import os

data = {}

for current in os.walk('/home/rank/'):

file_name = current[2][0]

date = file_name[:-4]

data[date] = 0

for line in open('/home/rank/%s' % file_name):

keyword, pos, url = line.rstrip().split('\t')

pos = int(pos)

if pos!=-1:

data[date] += 100 - pos

for date in data:

print '%s\t%d' % (date, data[date])

以一個數值的形式來量化整體的排名,數值越高則代表整體排名越好。 可以直接運行python analyse.py,看到分析結果。 但是光這樣的分析往往是不夠的,因為數位不是很形象,一般生成圖表會好得多。

儘管結合Google Chart Tools等API,可以自動生成圖表,但多數情況下不推薦這麼做,因為比較麻煩。 除非這些資料需要面向他人,或是需要每天都去分析排名趨勢資料。

一般來說可以這麼做:python analyse.py > data.csv

這條命令結合了Linux裡面的重定向>,此時程式不會再輸出內容到螢幕上,而是寫入到data.csv檔中。 之後即可使用如LibreOffice Calc(Linux下類似Excel的軟體)打開它,生成Line Chart來以圖形化的方式觀察分析資料。

思路擴展

一般來說需求決定技術做法,但這裡還是推薦初學者選下面的任意一個需求並實現它,不管目前是否有用。 因為熟悉一門程式語言最好的方法是多寫:

最簡單的擴展,將收集腳本從面向百度的改為可用於Google的。

可以再寫一個分析腳本,使用類似Google Analytics的高級細分的方式,做URL的篩選功能。 目前監控的是整個網站的流量趨勢,但在加入了篩選功能以後,可以統計諸如/article/和/photo/欄目不同的流量趨勢;也可對於同類欄目進行劃分,作為對於AB測試的效果追蹤。

可以再改進收集腳本,輔以關鍵字的搜索量與對於特定排名位置的大致點擊率,去估算網站所獲得的SEO流量的話,可以更全面的瞭解其情況。

可以再大幅改進收集腳本,將SERP上面所有出現的網站的排名都進行統計,則可以完全把握競爭對手的動態。 結合一些其它方面的監控以後,可以觀察到競爭對手絕大多數站內對SEO有意義的修改,並及時跟進。 (此時資料的儲存方式最好用資料庫來代替CSV,如使用MongoDB)

如果排名趨勢追蹤的需求非常重要的話,可以考慮做郵件每日報告及郵件預警之類功能。 Python裡面使用SMTP很容易,結合協力廠商郵箱的服務即可方便的發郵件。

技術擴展

文中涉及到了一些Python模組路徑及Linux環境變數的問題,雖然一般情況下把檔都放在~資料夾下面是可以的,但畢竟這樣子檔多了會很亂,可以去補充相關方面的知識。

文中提到了幾個模組,比如os和datetime等。 個人經驗是其中os模組用得不多,偶爾需要用的時候可以百度一下尋找使用方法。 而datetime平常用的不少,這些最好稍看下官方文檔,對使用到的幾個函數要瞭解:HTTP://docs.python.org/library/datetime.html

pycurl模組的使用,除了程式範疇之外,它還考驗對於Web的基礎知識。 比如REFERER等是什麼含義一定要理解,參見HTTP頭資訊有關的知識點。

不管是否選擇深入學習VIM編輯器,一定要牢記其打字和保存的方法,Linux裡面很多東西只能靠它編輯。

雖然文章中未提到,但採集資料中經常會遇到文字編碼問題。 UTF-8, GB2312等之間大致有什麼區別、Unicode又代表什麼、Python裡面怎麼轉換它們等,這些都需參考相關資料。

原文:HTTP://semwatch.org/2012/04/monitoring-rank/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.