来源:python中国网 时间:2019-07-15

  SEO人员都希望有一个排名监控系统,因为有时流量升降莫名其妙不好分析原因,此时一个排名监控体系可以帮助大家分析数据。之前发布过百度PC的代码,现在来实现mo端,关于百度mo端真实url的提取有两种方法,请查看此文:百度mo提取真实排名url。我们用第一种简单的,今天这个排名监控的实现是这样的:

  一:选一个行业,

  二:指定该行业几种类型的词(关键词文件kwd.xlsx。每个sheet的名字代表这类词的类别,每个sheet第一列放该类词),

  三:指定几个域名。(自己的站和竞品网站)。

  最后:结果是txt文件,记录当天日期下每个域名每类词首页词数量。

  手动:人工将结果累计在一个excel中,通过数据透视表+折线图功能来分析每个域名这几类词排名在首页的数量的变化!如下图:

代码如下

# ‐*‐ coding: utf‐8 ‐*‐
"""
提取的是自然排名url
不含百家号 百度知道 百度贴吧 不含xxx-视频(https://www.baidu.com/sf/vsearch?xxx) 但是含有百科
百家号 百度知道 百度贴吧 类名是c-container  xxx-视频是百度自己的页面
事先准备excel文件,每个sheet存储一类关键词,sheet名字即关键词分类
"""

from openpyxl import load_workbook
import requests
from pyquery import PyQuery as pq
import threading
import queue
import time
import json
import gc


class bdmoMonitor(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)

    # 读取excel文件 做好关键词分类
    @staticmethod
    def read_excel(filepath):
        q = queue.Queue()
        group_list = []
        wb_kwd = load_workbook(filepath)
        for sheet_obj in wb_kwd:
            sheet_name = sheet_obj.title
            group_list.append(sheet_name)
            col_a = sheet_obj['A']
            for cell in col_a:
                 kwd = (cell.value)
                 q.put({kwd:sheet_name})
        return q,group_list

    # 初始化结果字典
    @staticmethod
    def result_init(group_list):
        for domain in target_domain:
            result[domain] = {}
            for group in group_list:
                result[domain][group] = 0
        print("初始化结果字典成功")

    # 获取某词serp源码
    def get_html(self,url,retry=2):
        try:
            r = requests.get(url=url,headers=user_agent,timeout=5)
        except Exception as e:
            print('获取源码失败',url,e)
            if retry > 0:
                self.get_html(url,retry-1)
        else:
            html = r.text
            return html

    # 获取某词的serp源码上包含排名url的div块
    def get_data_logs(self, html):
        data_logs = []
        if html and '百度' in html:
            doc = pq(html)
            try:
                div_list = doc('.c-result').items()
            except Exception as e:
                print('提取div块失败', e)
            else:
                for div in div_list:
                    data_log = div.attr('data-log')
                    data_logs.append(data_log) if data_log is not None else data_logs
        return data_logs

    # 提取真实url
    def get_real_urls(self, data_logs=[]):
        real_urls = []
        for data_log in data_logs:
            # json字符串要以双引号表示
            data_log = json.loads(data_log.replace("'", '"'))
            url = data_log['mu']
            real_urls.append(url)
        return real_urls

    # 统计每个域名排名的词数
    def run(self):
        global success_num
        while 1:
            kwd_dict = q.get()
            for kwd,group in kwd_dict.items():
                url = "https://m.baidu.com/s?ie=utf-8&wd={0}".format(kwd)
                html = self.get_html(url)
                data_logs = self.get_data_logs(html)
                real_urls = self.get_real_urls(data_logs)
                print(real_urls)
                if real_urls:
                    # 将某词的serp上10条真实url合并为一个字符串
                    domain_str = ''.join(real_urls)
                    try:
                        threadLock.acquire()
                        success_num += 1
                        for domain in target_domain:
                            if domain in domain_str:
                                result[domain][group] += 1
                        print('查询成功{0}个'.format(success_num))
                    except Exception as e:
                        print(e)
                    finally:
                        threadLock.release()
                del kwd
                del group
                gc.collect()
            q.task_done()

    # 保存数据
    @staticmethod
    def save():
        print(result)
        print ('开始save.....')
        with open('bdmo_result.txt','w',encoding="utf-8") as f:
            for domain,data_dict in result.items():
                for key,value in data_dict.items():
                    f.write(date+'	'+domain+ '	'+key+'	'+str(value)+'
')


if __name__ == "__main__":
    start = time.time()

    # 全局变量 待监控域名列表
    target_domain = ['m.renrenche.com','www.renrenche.com','m.guazi.com','www.guazi.com',
                     'm.che168.com','www.che168.com','m.iautos.cn','so.iautos.cn','www.iautos.cn',
                     'm.hx2car.com','www.hx2car.com','58.com','m.taoche.com','www.taoche.com',
                     'm.51auto.com','www.51auto.com','m.xin.com','www.xin.com']
    user_agent = {
        'User-Agent': 'Mozilla/5.0 (Linux; Android 8.1.0; ALP-AL00 Build/HUAWEIALP-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.83 Mobile Safari/537.36 T7/10.13 baiduboxapp/10.13.0.11 (Baidu; P1 8.1.0)'}
    threadLock = threading.Lock()  # 锁
    result = {}   # 结果保存字典
    success_num = 0  # 查询成功个数
    date = time.strftime("%Y-%m-%d", time.localtime()) # 询日期

    q,group_list = bdmoMonitor.read_excel('kwd.xlsx')
    bdmoMonitor.result_init(group_list)
    all_num = q.qsize()

    # 设置线程数
    for i in list(range(5)):
        t = bdmoMonitor()
        t.setDaemon(True)
        t.start()
    q.join()

    bdmoMonitor.save()
    end = time.time()
    print('
关键词共{0}个,查询成功{1}个,耗时{2}min'.format(all_num,success_num,(end-start)/60) )
2019-07-14	m.renrenche.com	城市站	155
2019-07-14	m.renrenche.com	买车列表	135
2019-07-14	m.renrenche.com	品牌	7281
2019-07-14	www.renrenche.com	城市站	22
2019-07-14	www.renrenche.com	买车列表	12
2019-07-14	www.renrenche.com	品牌	1441
2019-07-14	m.guazi.com	城市站	184
2019-07-14	m.guazi.com	买车列表	77
2019-07-14	m.guazi.com	品牌	19446
2019-07-14	www.guazi.com	城市站	10
2019-07-14	www.guazi.com	买车列表	7
2019-07-14	www.guazi.com	品牌	2227
2019-07-14	m.che168.com	城市站	275
2019-07-14	m.che168.com	买车列表	185
2019-07-14	m.che168.com	品牌	15483
2019-07-14	www.che168.com	城市站	98
2019-07-14	www.che168.com	买车列表	43
2019-07-14	www.che168.com	品牌	2391
2019-07-14	m.iautos.cn	城市站	202
2019-07-14	m.iautos.cn	买车列表	193
2019-07-14	m.iautos.cn	品牌	12475
2019-07-14	so.iautos.cn	城市站	1
2019-07-14	so.iautos.cn	买车列表	0
2019-07-14	so.iautos.cn	品牌	399
2019-07-14	www.iautos.cn	城市站	11
2019-07-14	www.iautos.cn	买车列表	6
2019-07-14	www.iautos.cn	品牌	2831
2019-07-14	m.hx2car.com	城市站	44
2019-07-14	m.hx2car.com	买车列表	72
2019-07-14	m.hx2car.com	品牌	9647
2019-07-14	www.hx2car.com	城市站	65
2019-07-14	www.hx2car.com	买车列表	114
2019-07-14	www.hx2car.com	品牌	2005
2019-07-14	58.com	城市站	323
2019-07-14	58.com	买车列表	218
2019-07-14	58.com	品牌	19166
2019-07-14	m.taoche.com	城市站	34
2019-07-14	m.taoche.com	买车列表	9
2019-07-14	m.taoche.com	品牌	10895
2019-07-14	www.taoche.com	城市站	0
2019-07-14	www.taoche.com	买车列表	0
2019-07-14	www.taoche.com	品牌	836
2019-07-14	m.51auto.com	城市站	2
2019-07-14	m.51auto.com	买车列表	0
2019-07-14	m.51auto.com	品牌	22
2019-07-14	www.51auto.com	城市站	4
2019-07-14	www.51auto.com	买车列表	1
2019-07-14	www.51auto.com	品牌	44
2019-07-14	m.xin.com	城市站	252
2019-07-14	m.xin.com	买车列表	83
2019-07-14	m.xin.com	品牌	11794
2019-07-14	www.xin.com	城市站	32
2019-07-14	www.xin.com	买车列表	44
2019-07-14	www.xin.com	品牌	1336


  排名监控系统整体思路和实现就是这样的,当然也可以直接写在excel中,这个大家自己尝试吧。