ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python之爬取qq空间找说说

2022-03-20 09:02:48  阅读:209  来源: 互联网

标签:qq index python driver 空间 str print


记录一次爬取空间表白墙的图片

有一说一,python是真的简单,网上的资源也很全。本人作为一个连循环都写不明白的小白,也能用python做到想到的事。

爬取图片,只是为了把图片转换为文字,然后找一条特定的说说而已。

首先是登录

此段代码参考至博客

需要自行设置phantomjs.exe的路径。还有就是现在貌似加了滑块验证,或者是因为访问多了才有的限制,所以并没有用这个登录。

#!/usr/bin/python
# -*- coding:utf-8 -*-

from selenium import webdriver
import time

# 使用selenium
driver = webdriver.PhantomJS(executable_path="E:\\js\\bin\\phantomjs.exe")
driver.maximize_window()


# 登录QQ空间
def get_shuoshuo(qq):
    driver.get('http://user.qzone.qq.com/{}/311'.format(qq))  # 说说位于网页的/311界面下
    time.sleep(5)
    try:
        driver.find_element_by_id('login_div')
        a = True
    except:
        a = False
    if a == True:
        driver.switch_to.frame('login_frame')
        driver.find_element_by_id('switcher_plogin').click()
        driver.find_element_by_id('u').clear()
        # 选择用户名框
        driver.find_element_by_id('u').send_keys('你的qq号')
        driver.find_element_by_id('p').clear()
        driver.find_element_by_id('p').send_keys('你的qq密码')
        driver.find_element_by_id('login_button').click()
        time.sleep(3)
    driver.implicitly_wait(3)
    try:
        driver.find_element_by_id('QM_OwnerInfo_Icon')
        b = True
    except:
        b = False
        print("shibai")
    if b == True:
        driver.switch_to.frame('app_canvas_frame')
        content = driver.find_elements_by_css_selector('.content')
        stime = driver.find_elements_by_css_selector('.c_tx.c_tx3.goDetail')  # 可根据字段需要匹配多个元素
        for con, sti in zip(content, stime):
            data = {
                'time': sti.text,
                'shuos': con.text
            }
            print(data)

    cookie = driver.get_cookies()
    cookie_dict = []
    for c in cookie:
        ck = "{0}={1};".format(c['name'], c['value'])
        cookie_dict.append(ck)
    i = ''
    for c in cookie_dict:
        i += c
    print('Cookies:', i)
    print("==========完成================")

    driver.close()
    driver.quit()


if __name__ == '__main__':
    get_shuoshuo("别人的qq号")  # 需要爬取的qq

扫码登录

此段代码参考自知乎

亲测扫码登录可行,可以获得cookie。虽然对其中一些数据不太了解。

#!/usr/bin/python
# -*- coding:utf-8 -*-

#定义登录函数
import re
from time import sleep

from PIL import Image
from selenium import webdriver


def QR_login():
    def getGTK(cookie):
        """ 根据cookie得到GTK """
        hashes = 5381
        for letter in cookie['p_skey']:
            hashes += (hashes << 5) + ord(letter)
        return hashes & 0x7fffffff
    browser=webdriver.PhantomJS(executable_path="E:\\js\\bin\\phantomjs.exe")#这里要输入你的phantomjs所在的路径
    url="https://qzone.qq.com/"#QQ登录网址
    browser.get(url)
    browser.maximize_window()#全屏
    sleep(3)#等三秒
    browser.get_screenshot_as_file('QR.png')#截屏并保存图片
    im = Image.open('QR.png')#打开图片
    im.show()#用手机扫二维码登录qq空间
    sleep(15)#等二十秒,可根据自己的网速和性能修改
    print(browser.title)#打印网页标题
    cookie = {}#初始化cookie字典
    for elem in browser.get_cookies():#取cookies
        cookie[elem['name']] = elem['value']
    print('Get the cookie of QQlogin successfully!(共%d个键值对)' % (len(cookie)))
    print(cookie)
    html = browser.page_source#保存网页源码
    g_qzonetoken=re.search(r'window\.g_qzonetoken = \(function\(\)\{ try\{return (.*?);\} catch\(e\)',html)#从网页源码中提取g_qzonetoken
    gtk=getGTK(cookie)#通过getGTK函数计算gtk
    browser.quit()
    print("gtk ", gtk)
    print(g_qzonetoken)
    print("====")
    print(g_qzonetoken.__dict__)
    return (cookie,gtk,g_qzonetoken.group(1))
if __name__=="__main__":
    QR_login()

不过对本人而言,并不需要这么麻烦。

python实现带cookie的get请求就可以了。所以,我选择用fiddler。

操作:

1.打开fiddler,打开空间,使用fiddler观看数据包。

这个看得我有点懵,因为怎么加载也不会有jpg的数据包,但是网页内容命名有图片啊,于是直接分析网页数据
image

看看图片的链接。找到了这个 phototj.photo.store.qq.com/psc 这个就是图片的请求了。

于是对网页切换页数,观察数据包,确定加载网页内容的链接。

得到了这个

https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6

这个实际是get请求,末尾带很多参数,可以通过fiddler查看。

保存这条链接的响应,打开txt,果然能搜到很多phototj.photo.store.qq.com/psc

那就是确认无疑了。

2.不停切换网页页数,看看加载不同页,请求的差别在哪里。

参数很多,但是经过测试验证,只需要pos和num属性。其中num不变为20,pos为每次加载的起点。

比如第一页,pos=0,第二页,pos=20,第三页,pos=40.因为每一页固定20条说说。

3.利用fiddler的composer功能,把上面链接的请求视图中的所有内容复制到里面,

复制到Raw里面,点击Execute,看看有什么响应。主要看看是不是和网页点击加载出来的一样。

还有就是改变pos的数值,看看加载内容的变化。

测试完毕,一切都好,那就没问题了。接下来只要python能发出一样的请求就好了。
image

4.使用python发出get请求并处理数据

代码:

Get获取数据内容

def getContent(pos):
    url = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?pos=' + str(pos) + '&num=20' #作为博客,我删减了其他get参数,用的时候,复制fiddler的get链接,然后修改成类似这样就好了。
    header = {
        'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="99", "Microsoft Edge";v="99"',
        'sec-ch-ua-mobile': '?0',
        'Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36 Edg/99.0.1150.46',
        'sec-ch-ua-platform': '"Windows"',
        'Referer': '根据上面第3点里面的内容改',
        'Cookie': '你自己的cooke'
    }

    web = requests.get(url, headers=header)
    data = web.content
    soup = BeautifulSoup(data, "html.parser")  # 多种解析器,这里选这个就够用了
    getPhotoUrl(soup.prettify())

处理数据(注意下面的代码要放到上面的上面,这里只是按照处理的先后顺序贴代码)

filename = "url.txt"
filea = open(filename, "a", encoding='utf-8')
def getPhotoUrl(str):
    str = str.replace("_Callback(", ""); #需要做一些处理,才能转换为json
    str = str.replace("}});", "}}") #作者作为小白,一直用str.replace没反应,才想起str = str.replace
    # print(str)
    obj = json.loads(str)
    print(str)
    # for data in obj:
    #     print(obj[data])

    if obj['msglist'] == None:  #调试了半天,原来是没有数据了。
        print("none")
    else:
        for data1 in obj["msglist"]:
            if 'pic' in data1: #这都是坑,有的里面没有图片
                for data2 in data1["pic"]:
                    if 'smallurl' in data2: #这都是坑,有的里面没有图片
                        print(data2["smallurl"], file=filea)

运行代码:

for i in range (60):#空间看着有150多页,实际到59页就没有数据了
    print(i)
    getContent(i*20)#60

结果:
image

上面json取数据怎么来的:

第3步的时候,利用fiddler查看响应,切换到json即可。一开始还傻傻的手动分割数据。

5.读取url.txt,下载图片到文件夹。

代码:

def writeData(index,data):
    filename = './picture/' + str(index) + ".jpg"
    file = open(filename,"wb")
    file.write(data)
    file.close()

file = open("url.txt","r")
url = file.readline()
index = 0
while url:
    url = url.replace("\n","")
    obj = requests.get(url=url)
    writeData(index,obj.content)
    url = file.readline()
    index = index + 1
print("finish")

需要注意的事,本人只是想做这件事而已,并不在意什么规范。所以都是一个python文件,一个函数,做一件事的。不要全部代码复制到一个tet,然后运行不了啥的。

运行结果:
image

6.识别图片,保存识别内容到txt

代码:

#!/usr/bin/python
# -*- coding:utf-8 -*-

import pytesseract
from PIL import Image
# 读取图片
# im = Image.open('3.jpg')
# 识别文字
# string = pytesseract.image_to_string(im,lang='chi_sim')
# print(string)


index = 500 #500条500条的识别,找到我要的说说就不弄了。
for i in range(500):
    filename = './picture/' + str(i+index) + ".jpg"
    im = Image.open(filename)
    string = pytesseract.image_to_string(im, lang='chi_sim')
    print(i+index)
    # print("index = ",str(i)," ",string,file = filea)
    stra = "index = " + str(i+index) + " " + string
    filea = open("data.txt", 'a', encoding='utf-8')#注意要加encoding=‘utf-8' 因为默认是ansi编码
    filea.write(stra)

7.总结:

python真是好用啊,看着控制台输出的排列整齐的数据,感觉好像很厉害。

主要是这个发送请求很方便。

之前在爬取小说的时候,一开始是用的Qt里面的post,结果请求多了,线程太多就崩了。但是python不会,请求9000多个链接,也不会怎么样。

还有就是fiddler也是网页分析的利器啊,没有fiddler,想提取数据都要费好大劲了。

标签:qq,index,python,driver,空间,str,print
来源: https://www.cnblogs.com/dayq/p/16028940.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有