Pythonを使ってQQの友达の言うことを登ります

17939 ワード

个人のブログは先日QQの友达の话を登ってきて大体12 Wのデータが登ったことを统计してそれからこれらのデータを简単な可視化の分析を行った后に突然すべての友达の分析の考え方を分析することができるかどうかを考えて、先端は相応のQQを入力してそのQQの分析の结果を表示することができてあるいは学友の提案を闻いて1つの縁のAPPをして揺らします携帯は他の人の言うことを見ることができて、考えてみるととても游んで、时間があったらこれを完璧にしました.
開発環境:
  • python3.5
  • MySQL5.7
  • Ubuntu16.04LTS
  • Pythonサードパーティライブラリ
  • selenium
  • Requests
  • pymysql
  • jieba
  • wordcloud

  • QQ空間爬虫ステップ:
  • selenium+phantomjsシミュレーションにより登録qq空間からcookiesとg_を取得qzonetoken,gtk(リクエストパラメータが暗号化されているため)
  • を算出する.
  • Requestsライブラリを介して前に取得するURLパラメータを介してhttpリクエスト
  • を構築する.
  • 解析要求応答は、正規マッチングにより所望のフィールド(jsonライブラリで直接取り出すこともできる)
  • を利用する.
  • 一致する情報に基づいてデータベーステーブルを設計して
  • に入庫する.
  • qqメールボックスの连络先をエクスポートする机能を通じて(通って)友达のQQ号をcsvファイルにエクスポートしてそれからすべてのQQ号を遍歴してすべての话を取ります
  • 以降のデータ分析
  • コード実装
  • selenium+phantomjsシミュレーションにより登録qq空間からcookiesとg_を取得qzonetoken,gtk(リクエストパラメータが暗号化されているため)
  • を算出する.
    from selenium import webdriver
    import time
    import re
    
    
    #  cookie,g_tk,g_qzontoken     
    def Login_QQ():
        '''gtk  '''
        def getGTK(cookie):
            """   cookie  GTK """
            hashes = 5381
            for letter in cookie['p_skey']:
                hashes += (hashes << 5) + ord(letter)
            gtk=hashes&0x7fffffff
            return gtk
    
        browser=webdriver.Chrome()
        url = "https://qzone.qq.com/"  # QQ    
        browser.get(url)
    
        browser.switch_to.frame('login_frame')#        
        browser.find_element_by_id('switcher_plogin').click()
    
        browser.find_element_by_id('u').clear()
        browser.find_element_by_id('u').send_keys('')  #       QQ 
        browser.find_element_by_id('p').clear()
        browser.find_element_by_id('p').send_keys('')  #       QQ  
    
        browser.find_element_by_id('login_button').click()
        time.sleep(1)
        print(browser.title)  #       
        # print(browser.get_cookies())
        cookie={}
        for element in browser.get_cookies():
            cookie[element['name']]=element['value']
        print('Get the cookie of QQlogin successfully!( %d    )' % (len(cookie)))
        print(cookie)
        html = browser.page_source  #       
        pattern = re.compile(r'window\.g_qzonetoken = \(function\(\)\{ try\{return "(.*?)";\}')
        g_qzonetoken=re.search(pattern,html)
        print(g_qzonetoken.group(1))
        gtk=getGTK(cookie)#  getGTK    gtk
        return (cookie,gtk,g_qzonetoken)
    
    

    実はseleniumのスクリーンショット機能でスキャン登録もできます
    Requestsライブラリで前に得られたurlパラメータを用いてhttpリクエストを構築する
    自分のスペースを開いてブラウザ開発者モードを開き、XHRとPreservce logをクリックします.
    そして自分のスペースでクリックするとこんなURL(emotion_cgi_msglis_v 6?uin=×××××)
    previewをクリックすると必要な情報が表示されます
    このリクエストヘッダには、2つのパラメータが不確定であることがわかります.
    g_tk qzonetoken中g_tkは、ある暗号化アルゴリズムによって生成されたg_であるtk具体的な説明
    qzonetokenはWebソースで直接見つけることができます
    コンストラクションのリクエストパラメータを取得するとurlをコンストラクションし、必要なフィールドを正規で抽出できます(正規がかっこいいと思うので正規を採用します)
    def parse_mood(i):
    '''    json ,         '''
    qq=get_qq()
    text = re.sub('"commentlist":.*?"conlist":', '', i)
    if text:
        myMood = {}
        myMood["isTransfered"] = False
        tid = re.findall('"t1_termtype":.*?"tid":"(.*?)"', text)[0]  #     ID
        tid = qq + '_' + tid
        myMood['id'] = tid
        myMood['pos_y'] = 0
        myMood['pos_x'] = 0
        mood_cont = re.findall('\],"content":"(.*?)"', text)
        if re.findall('},"name":"(.*?)",', text):
            name = re.findall('},"name":"(.*?)",', text)[0]
            myMood['name'] = name
        if len(mood_cont) == 2:  #      2        
            myMood["Mood_cont"] = "  :" + mood_cont[0] + "--------->    :" + mood_cont[1]  #     
            myMood["isTransfered"] = True
        elif len(mood_cont) == 1:
            myMood["Mood_cont"] = mood_cont[0]
        else:
            myMood["Mood_cont"] = ""
        if re.findall('"created_time":(\d+)', text):
            created_time = re.findall('"created_time":(\d+)', text)[0]
            temp_pubTime = datetime.datetime.fromtimestamp(int(created_time))
            temp_pubTime = temp_pubTime.strftime("%Y-%m-%d %H:%M:%S")
            dt = temp_pubTime.split(' ')
            time = dt[1]
            myMood['time'] = time
            date = dt[0]
            myMood['date'] = date
        if re.findall('"source_name":"(.*?)"', text):
            source_name = re.findall('"source_name":"(.*?)"', text)[0]  #        (    )
            myMood['tool'] = source_name
        if re.findall('"pos_x":"(.*?)"', text):
            pos_x = re.findall('"pos_x":"(.*?)"', text)[0]
            pos_y = re.findall('"pos_y":"(.*?)"', text)[0]
            if pos_x:
                myMood['pos_x'] = pos_x
            if pos_y:
                myMood['pos_y'] = pos_y
            idname = re.findall('"idname":"(.*?)"', text)[0]
            myMood['idneme'] = idname
            cmtnum = re.findall('"cmtnum":(.*?),', text)[0]
            myMood['cmtnum'] = cmtnum
        return myMood
    

    データを取得してから入庫してテーブルを作成する
    CREATE TABLE `mood` (
    `name` varchar(80) DEFAULT NULL,
    `date` date DEFAULT NULL,
    `content` text,
    `comments_num` int(11) DEFAULT NULL,
    `time` time DEFAULT NULL,
    `tool` varchar(255) DEFAULT NULL,
    `id` varchar(255) NOT NULL,
    `sitename` varchar(255) DEFAULT NULL,
    `pox_x` varchar(30) DEFAULT NULL,
    `pox_y` varchar(30) DEFAULT NULL,
    `isTransfered` double DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    実はここまで主要な爬虫类のコードはすでに终わった后にQQメールボックスの连络先を通じて(通って)机能を导いてURLのリストを构筑してすべての友达の情报を爬虫类することができます(访问者の记录がありません)私は1スレッドで大体3时间爬虫类のコードを爬虫类しました
    mport pymysql
    import re
    import requests
    import datetime
    from qq.Login import Login_QQ
    from qq.getFriends import getFriends
    from qq.mood import parse_mood
    
    host='localhost'
    user=''
    pwd=''
    db=''
    
    con=pymysql.connect(host,user,pwd,db,use_unicode=True, charset="utf8")#     
    cursor=con.cursor()
    con.autocommit(True)
    
    #       
    headers = {
        xxx
    }
    
    cookie,gtk,qzonetoken=Login_QQ()#        cookies,gtk,qzonetoken
    s=requests.session()# requests     
    
    friends=getFriends()
    
    for qq in friends:#  qq   
        for p in range(0,1000):
            pos=p*20
            params={
            'uin':qq,
            'ftype':'0',
            'sort':'0',
            'pos':pos,
            'num':'20',
            'replynum':'100',
            'g_tk':gtk,
            'callback':'_preloadCallback',
            'code_version':'1',
            'format':'jsonp',
            'need_private_comment':'1',
            'qzonetoken':qzonetoken,
            'g_tk': gtk
            }
    
            response=s.request('GET','https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?',params=params,headers=headers,cookies=cookie)
            if response.status_code==200:
                text=response.text
    
                if not re.search('lbs',text):#  lbs   qq         
                    print("%s      "%qq)
                    break
                textlist=re.split('\{"certified"', text)[1:]
                for i in textlist:
                    myMood=parse_mood(i)
    
                    '''         mysql   ,             bug    ,                          '''
                    try:
                        # #  
                        # same_sql = '''
                        #     select %s from mood
                        # '''
                        # cursor.execute(same_sql,myMood['id'])
                        # if  cursor.fetchall():
                        #     print("       ")
                        insert_sql = '''
                                              insert into mood(id,content,time,sitename,pox_x,pox_y,tool,comments_num,date,isTransfered,name)
                                              VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
                                           '''
                        cursor.execute(insert_sql, (
                        myMood['id'], myMood["Mood_cont"], myMood['time'], myMood['idneme'], myMood['pos_x'],
                        myMood['pos_y'], myMood['tool'], myMood['cmtnum'], myMood['date'], myMood["isTransfered"],
                        myMood['name']))
    
                    except:
                        pass
    
    print('        !')

    爬虫類の内容が終わった後のデータ分析Flask+Echartsで完了したステップの後に追加します.