乔向阳:项目驱动学Python编程,一箭双雕【据说不会Python的都不是好SEOer】

  • A+
所属分类:SEO好文章
本文信息本文由方法SEO顾问发表于2017-07-0718:09:40,共 6367 字,转载请注明:乔向阳:项目驱动学Python编程,一箭双雕【据说不会Python的都不是好SEOer】_【方法SEO顾问】,如果我网站的文章对你有所帮助的话,来百度口碑给个好评呗!

最近需要对聚合页面SEO做研究,为了对比分析需要记录各同行网站的关键词排名情况。

手工记录的话效率太低,样本数量也有限。

于是要把这部分工作自动化,因为自学过PHP编程,实现这个需求没问题。

但我打算使用Python,给自己一天的时间边学边写代码,用项目来驱动Python学习。

不是完全的零基础,去年看过廖雪峰的Python3教程

但“看过”与“用过”差距真是不小,这几天仅靠Google和Stackoverflow,居然解决了一个个坑,把任务完成了。

我把整个需求和代码贴出来,作为自己的总结,也希望给大家一些参考。

获取待监测的关键词

从爱站网可以查看某个网站特定目录的关键词和排名(支持PC和移动),流量统计当然可以获取更多关键词,但是无法获取关键词指数。

比如,查看我们网站PC“产品词”页面获得关键词排名,按指数由高到低排序。http://baidurank.aizhan.com/baidu/huangye88.com/product/0/1/exp/-1/...

想要导出这些词,需要爱站网账号,没有可以自己写程序抓取。

代码和注释如下:

#coding:utf-8
#导入正则库
import re
#导入sys库,为了使用sys.exit()中断调试使用。
import sys
#python3中只要urllib库,没有urllib2,这里导入urllib.request用于请求页面采集
import urllib.request
#导入这个库为了对中文进行URL编码
import urllib.parse
#导入这个库为了让抓取程序暂停1秒采集,避免太快被封
import time
#这个库需要按照 pip install var_dump ,类似于php的var_dump,调试代码时使用
from var_dump import var_dump
#python的xpath类库,让采集规则支持xpath语法,降低采集难度
from lxml import etree

#定义一个方法通过URL获取页面HTML代码
def getHTML(url):
    #定义请求的header,伪装请求。对于爱站来说,如果没有referer地址,无法采集正确页面。
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)',
        'Referer':'[百度一下,你就知道](http://www.baidu.com)'
    }
    # 构建一个http请求,使用自定义的headers信息
    req = urllib.request.Request(url, headers = headers)
    # 代码睡1秒
    time.sleep(1)
    # 采集信息,获得一个html代码对象
    html_obj = urllib.request.urlopen(req)
    # 读取html源代码为字符串,并用utf-8编码输出
    html = html_obj.read().decode("utf-8")
    return html

# 定义一个获得特定网站的爱站关键词的方法
def getWords(url, website):
    # 根据URL获得HTML代码
    source = getHTML(url)
    # print(source)
    # 转化为支持Xpath的DOM结构
    selector = etree.HTML(source)
    # 写Xpath语法,获取页面中class为word_record_w的a标签的所有文本,也就是关键词
    words = selector.xpath('//a[@class="word_record_w"]/text()')
    #循环把一个个词写入aizhan_word_网站域名.txt的文件中
    for item in words:
        print(item.strip())
        # 打开文件,使用append模式写入关键词,一行一个,strip()用于去掉关键词前后的空白
        with open('./aizhan_word_' + website + '.txt', 'a') as f:
            f.write(item.strip() + "\n")

# 爱站最多显示50页,从第一页开始,构造各个分页的URL
for x in range(1,51):
    # 为了以后能适用采集别的网站,这里单独给网站设置一个变量
    website = "huangye88.com"
    # 为了支持不同的目录,同理设置一个变量
    dirname = "product"
    # 因为x是数字,为了拼URL,需要用str(x)转化为字符串
    url = "[站长工具_百度权重查询 - 爱站网](http://baidurank.aizhan.com/baidu/)"+ website +"/"+ dirname +"/0/"+ str(x) +"/exp/-1/"
    # 开始采集关键词
    getWords(url, website)

采集百度搜索结果页

我们已经获得了一个包含几千关键词的文本文件:

下一步需要使用这些关键词把百度前几页的搜索结果拿到,当出现下面域名时,把对应的网址、标题、排名、关键词、日期写入Mysql数据库中。

http://huangye88.com’‘http://hc360.com’‘http://1688.com’‘http://china.cn’‘http://makepolo.com’‘http://b2b168.com’‘http://liebiao.com

上面域名对应B2B行业网站黄页88网、慧聪网、阿里巴巴、中国供应商、马可波罗网、八方资源网、列表网,你可以根据自己想监测的竞争对手网站调整。

代码如下:

#encoding=utf-8
import re
import sys
import urllib.request
import urllib.parse
import time
# 需要获取日期,所以导入这个库
import datetime
# 需要解析JSON文件
import json
from var_dump import var_dump
from lxml import etree
# 连接Mysql数据库,使用pymysql数据库,研究对比了几个,python3大家用这个多
import pymysql

# 定义一个根据URL获取HTML代码的方法
def getHTML(url):
    req = urllib.request.Request(url)
    html_obj = urllib.request.urlopen(req)
    html = html_obj.read().decode("utf-8")
    return html

# 定义一个获得搜索结果页面的方法
def getSERP(word):
    # 把关键词做URL encoding
    newword = urllib.parse.quote(word)
    # 拼出来一个百度搜索结果页地址,注意下面是样例,非正式地址。
    url = "[百度一下,你就知道](http://www.baidu.com/s?wd=)"+ newword +"&xxx=0&xxx=50&xxx=json"
    html = getHTML(url)
    # 把html源代码转化为JSON对象
    html = json.loads(html)
    获得一条条搜索结果记录
    items = html['feed']['entry']
    # 循环整个数组,index+1就是对应的排名
    for index,value in enumerate(items):            # 如果包含url这个属性,则读出网址、标题和排名
        if 'url' in value:
            item_url = value['url']
            item_title = value['title']
            item_rank = index + 1
            # 所以希望记录的网址特征符
            all_websites = ['huangye88.com', 'hc360.com', '1688.com', 'china.cn', 'makepolo.com', 'b2b168.com', 'liebiao.com']
            # 今天的日期
            now = datetime.datetime.now()
            # 转化成年月日格式的字符串 ,比如2017-06-26
            today = now.strftime('%Y-%m-%d')
            # 如果URL中包含all_websites中的任意特征符则打印出来网址、标题和排名
            if any(item in item_url for item in all_websites):
                print(item_url)
                print(item_title)
                print(item_rank)
                # 构造一个字典对象
                line = {"title":item_title, "url":item_url, "rank":item_rank, "kw":word, "date": today}
                # 写入Mysql数据库
                saveIntoDB(line)

# 定义一个写入数据库的方法
def saveIntoDB(line):
    # 尝试写入,避免出错直接跳出
    try:
        # 连接数据库的方法,记住需要加charset='utf-8' 否则terminal读取显示会有乱码
        db = pymysql.connect("localhost","Mysql用户名","Mysql密码","数据库名", charset='utf8')
        # 数据库操作指针
        cursor = db.cursor()
        # 执行写入操作
        effect_row = cursor.execute("insert into b2b_kw_rank(title,url,rank,kw,date) values(%s,%s,%s,%s,%s)", (line["title"], line["url"], line["rank"], line["kw"], line["date"]))            # 提交写入操作,否则不会写入
        db.commit()
        # 关闭数据库连接
        db.close()
    except:
        pass

# 读取文件,一行一个
for line in open("aizhan_word.txt"):
    # 去掉前后空格
    word= line.strip()
    # 执行获取搜索结果页的函数
    getSERP(word)

数据库结构:

为了简化程序写法,而且搜索引擎更新没有那么频繁,所以每个URL每天只记录一条,把url和data联合做一个unique索引。

程序运行后的结果:

后续分析

有了数据,以后可以对这些关键词进行单独分析,监测各关键词搜索结果的排名变化情况,从而判断各个竞争对手网站的SEO效果,进一步分析页面做法。

导出了一天的数据,使用Excel做一些粗略分析:

至少对于这1200多个词说,各家网站的平均排名如下:

阿里巴巴是当之无愧的老大,SEO效果最好,甚至好的有些过分。

一页结果7个来自阿里巴巴,着陆页为各种聚合页面,不讲理的强!

据说阿里巴巴的聚合页面每个都有6~30个外链,外链来自于自己养的25万站群。(待考证)

各B2B网站SEO排名好的聚合页面

阿里巴巴

kq目录(229)

http://s.1688.com/kq/-BBAFD7B1C6B7B0C5B1C8CDDECDDE.html...

chanpin目录(178)

http://www.1688.com/chanpin/-B0ECB9ABD7C0D2CE.html...

topic目录(68)

http://www.1688.com/topic/jiamenglengyin.html...

jiage目录(46)

http://www.1688.com/jiage/-C4BECCC7.html...

market目录(33)

http://www.1688.com/market/-B8E2B5E3CAA6C5E0D1B5.html...

慧聪网

hots站内热搜词聚合(201)

http://www.hc360.com/hots-eoz/907362987.html...

cp目录(169)

http://www.hc360.com/cp/upanshexiangji01.html...

price目录(115)

http://www.hc360.com/price/caitiaobu.html...

pic目录(102)

http://www.hc360.com/pic/tieyihuajia.html...

列表网

cp目录(163)

http://www.liebiao.com/cp/dianshijieshouqiquantao/...

wenda目录(57)

http://www.liebiao.com/wenda/fukangzhichuangshouye/...

ABC聚合页(19)

http://www.liebiao.com/abcw0s4zu/

马可波罗网

MPP聚合目录(352)

http://china.makepolo.com/mpp_53/gefqbbm6938.html...

chanpin目录(161)

http://china.makepolo.com/chanpin/4egd17vleau.html...

cp价格聚合(54)

http://b2b.makepolo.com/cpinfo/jiage/ms2142276.html...

cp聚合页(43)

http://b2b.makepolo.com/cpinfo/ac3305336.html...

cp图片聚合(23)

http://b2b.makepolo.com/cpinfo/tupian/tg1805766.html...

pinpai聚合(15)

http://b2b.makepolo.com/pinpai/t60400.html...

中国供应商

search目录(90)

https://www.china.cn/search/BE16AB8FBDC5DBB0DF0CAD17DB00CBDBDF5AED.html...

subject目录(17)

https://www.china.cn/subject/xiaoxingjiguangqiegeji.html...

附录:各大B2B网站常规的聚合页做法简单介绍

1、收集整理大量长尾词。

来源可能如下:A:用户站内搜索词B:用户发布信息时填写的关键词、品牌词等C:百度搜索相关词、下拉词拓展D:采集竞争对手网站词库…

2、分析整理词库,设计着陆页

借助人工或搜索分析,把词归类,定制聚合页面。

使用关键词调用站内的信息和公司等资料,生成聚合页面。

注意:设计聚合页需要针对性的定制页面TDK规则、布局和模块规则,避免不同聚合页内容重复。

URL常见有三种做法:A、中文拼音 B、对关键词进行Dehex编码处理 C、数字ID

这三种方法各有利弊,阿里巴巴的URL方式可以对关键词方便的编码加工和反加工,不怕空格和特殊字符,这点比拼音有优势。

甚至我们还使用过中文URL,后来证明容易出各种抓取上的问题,不建议。

Dehex编码(问技术要的):

// 对关键词做dehex编码处理(PHP版本)
function encode($word){
        $length = strlen($word);
        $asc = '';
        for($i=0; $i<$length; $i++){
            $asc .= dechex(ord($word[$i]));
        }
        return strtoupper($asc);
    }
// 对关键词做解码处理(PHP版本)
function decode($str){
    $parts = str_split($str, 2);
    $word = '';
    foreach ($parts as $part){
        $word .= chr(hexdec($part));
    }
    return $word;
}

3、推广聚合页面

A、提交SitemapB、在蜘蛛抓取频繁页面增加入口地址C、增加反向链接

文章来源:乔向阳的知乎专栏

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: