在Python学习热潮下,很多人掌握基本语法后却找不到合适案例上手。其实,QQ空间操作是个不错的练手项目。下面就详细说说怎么利用这个案例进一步提升编程能力。
登陆准备
def search_cookie():
qq_number = input('请输入qq号:')
if not __import__('os').path.exists('cookie_dict.txt'):
get_cookie_json(qq_number)
with open('cookie_dict.txt', 'r') as f:
cookie=json.load(f)
return True
def get_cookie_json(qq_number):
password = __import__('getpass').getpass('请输入密码:')
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
login_url = 'https://i.qq.com/'
chrome_options =Options()
chrome_options.add_argument('--headless')
driver = webdriver.Chrome(options=chrome_options)
driver.get(login_url)
driver.switch_to_frame('login_frame')
driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click()
time.sleep(1)
driver.find_element_by_xpath('//*[@id="u"]').send_keys(qq_number)
driver.find_element_by_xpath('//*[@id="p"]').send_keys(password)
time.sleep(1)
driver.find_element_by_xpath('//*[@id="login_button"]').click()
time.sleep(1)
cookie_list = driver.get_cookies()
cookie_dict = {}
for cookie in cookie_list:
if 'name' in cookie and 'value' in cookie:
cookie_dict[cookie['name']] = cookie['value']
with open('cookie_dict.txt', 'w') as f:
json.dump(cookie_dict, f)
return True
def get_g_tk():
p_skey = self.cookie['p_skey']
h = 5381
for i in p_skey:
h += (h << 5) + ord(i)
g_tk = h & 2147483647
对于QQ空间操作,登陆是首要步骤。不过上期我已经详细讲过,这里就不多说登陆问题。我们主要关注cookie信息和g_tk参数。这俩参数是操作空间的敲门砖,有了它们才能继续后续动作。
有了cookie信息和g_tk参数后,就可以尝试进入空间,为获取好友动态的XML位置做准备。只有成功登陆,后续查找工作才能顺利进行。
寻找XML位置
成功登陆后,开始寻找空间好友动态的XML位置。在页面里一个个去查找,发现有个叫feeds3_html_more的很可能是我们要找的。点进去一看,还真是所需的url链接。
def get_space():
your_url = 'https://user.qzone.qq.com/' + str(qq_number)
html = requests.get(your_url,headers=headers,cookies=cookie)
if html.status_code == 200:
qzonetoken = re.findall('window.g_qzonetoken =(.*?);',html.text,re.S)[1].split('"')[1]
return True
虽然找到了链接,但这个链接所需的参数不少。需要我们逐个去识别和收集,这样才能通过这个链接获取到想要的内容。
处理参数细节
'rd': '0.9311604844249088',
'windowId': '0.51158950324406',
qzonetoken参数在源码里较为特殊,它是个可变的“定值”。每次刷新页面这个参数都会变,不过源码里会给出其具体值,我们只要提取出来就行。
'usertime': str(round(time.time() * 1000)),
而windowId和rd参数,经过多次实验发现,刷新结果虽不同,但对整体没什么影响,直接抄下来用就可以,不用太在意它们的变化。
def get_g_tk():
p_skey = self.cookie['p_skey']
h = 5381
for i in p_skey:
h += (h << 5) + ord(i)
g_tk = h & 2147483647
获取与处理网页返回值
拿到XML和各个参数后,便能访问网页获取返回值。但这个返回值和其他的不一样,它不只是个json文件,无法直接转换为字典格式供我们使用,这就麻烦了。
拿到字符串后,先把前后不一致的部分切片扔掉。即便经过一系列处理,还是难以将像json格式的字符串转成字典。不过可以用demjson直接将该字符串转换为字典,提取data里的data,这就是前八条动态的参数,我们先取第一条说说的信息。
提取关键信息
# 例子
# -*- coding: utf-8 -*-
import demjson
js_json = "{x:1, y:2, z:3}"
py_json1 = "{'x':1, 'y':2, 'z':3}"
py_json2 = '{"x":1, "y":2, "z":3}'
data = demjson.decode(js_json)
print(data)
# {'y': 2, 'x': 1, 'z': 3}
data = demjson.decode(py_json1)
print(data)
# {'y': 2, 'x': 1, 'z': 3}
data = demjson.decode(py_json2)
print(data)
# {'y': 2, 'x': 1, 'z': 3}
拿到第一条说说信息后,开始提取我们关心的内容。像名字、QQ号、发布时间、获赞数、说说内容、说说地址等。这里面包含了很多有价值的信息。
另外,在qq_spaces参数里有个很长很特殊的html结果。它类似于网页常规代码,像是被JavaScript写入网页的。由于不是完整代码,只能用正则表达式提取我们需要的内容。
text = html.text[10:-2].replace(" ", "").replace('\n','')
json_list = demjson.decode(text)['data']['data']
qq_spaces = json_list[0]
实现点赞功能及更新判断
若要给说说点赞,先清空原来动态产生的抓包,点个赞会发现关于dolike的url有三个。其中第一个POST请求的url,大概率就是我们要的点赞网址。
获取到点赞URL后,得找到里面所需参数。opuin参数是自己的QQ号,可直接从代码提取;unikey和curkey参数是被点赞方的说说链接,前面已经获取。不过因为树莓派性能等原因,代码做不到绝对秒赞。
content = str(qq_spaces['html'])
try:zanshu = re.findall('(.*?)人觉得很赞
为了实现更新判断和持续使用,在本地建个文件,写入最后一条说说的时间戳。比对当前时间戳和空间第一条说说是否相同,若相同说明无更新。点赞后重写文件,下次运行代码就能继续尝试秒赞。
你在学习Python找案例上手时,遇到过什么特别难解决的问题吗?欢迎点赞、分享本文,并在评论区留言。