时间:2023-01-18 07:49:02 | 来源:电子商务
时间:2023-01-18 07:49:02 来源:电子商务
从这篇文章开始不打算再花费大量精力去写程序本身的知识,毕竟是各类书籍上有的内容。其余主要需要学习的是内置函数的使用,和一些模块的使用方式,尤其是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(';), 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(';) #这样即下载了一个网页
#以下是比较保险的下载方式,因为各种原因,就算总体很稳定的网站也偶尔会出现网页暂时无法打开的情况
#当网页下载出错时,如果retry为True,则会不断重试,直到下载完网页
#delay则指定了几次重试之间的时间间隔,以秒为单位
print curl.curl(';, retry=True, delay=1)
#以下用到了一些Curl的参数,详细说明可见:
print curl.curl(';, FOLLOWLOCATION=False, COOKIE='mycookie')
关键词:实现,关键