参考
代码地址
大致流程
- 使用
selenium
登录QQ空间 - 获取登录后的
token
- 获取登录后的
cookies
并通过cookies
和空间加密算法得到g_tk
字串,后期请求链接需要 - 构造
session
后期所有请求可以直接使用session
- 请求留言板数据,转换为
json
格式,去掉HTML
标签存入txt
使用selenium
登录QQ空间
# path是chromedriver.exe路径
driver = webdriver.Chrome(path)
# URL = 'https://user.qzone.qq.com/'
driver.get(URL)
# 切换视图,要不然会找不到元素
driver.switch_to_frame('login_frame')
# 模拟点击切换账号密码登录
driver.find_element_by_id('switcher_plogin').click()
# 自动输入QQ账号
driver.find_element_by_id('u').send_keys(user)
# 自动输入QQ密码
driver.find_element_by_id('p').send_keys(pwd)
# 模拟登陆点击
driver.find_element_by_id('login_button').click()
获取token
html = driver.page_source
xpat = r'window\.g_qzonetoken = \(function\(\)\{ try{return \"(.*)";'
qzonetoken = re.compile(xpat).findall(html)[0]
获取cookies
,获取g_tk
realCookie = {}
print(cookies)
for elem in cookies:
realCookie[elem['name']] = elem['value']
g_tk = get_g_tk(realCookie)
def get_g_tk(cookie):
hashes = 5381
for letter in cookie['p_skey']:
hashes += (hashes << 5) + ord(letter) # ord()是用来返回字符的ascii码
return hashes & 0x7fffffff
获取session
def back_session(realCookie):
session = requests.session()
c = requests.utils.cookiejar_from_dict(realCookie, cookiejar=None, overwrite=True)
session.headers = headers
session.cookies.update(c)
return session
保存留言板,通过递归实现
#保存留言板
def saveWords(session, gtk, token, start=0, limit=10):
print('当前下载第%d页数据'%(start/10+1))
url = 'https://user.qzone.qq.com/proxy/domain/m.qzone.qq.com' \
'/cgi-bin/new/get_msgb?uin=%s&hostUin=%s&start=%s' \
'&s=0.1698142305644994&format=jsonp&%s=10&inCharset=utf-8' \
'&outCharset=utf-8&g_tk=%s&qzonetoken=%s&g_tk=%s' % (user, user, start, limit, gtk, token, gtk)
res = session.get(url)
text = res.text
#去掉返回json中的_CallBack以及后面的); 才能格式化为json
text = text[10:-3]
j = json.loads(text)
total = j['data']['total']
with open(txt+'txt', 'a', encoding='UTF-8') as f:
if start == 0:
f.write('总共有%s条留言\n' % total)
f.write('当前下载第%d页数据\n'%(start/10+1))
for value in j['data']['commentList']:
cont = str(value['pubtime']) + ' ' + str(value['uin']) + '-' + str(value['nickname']) + ':' + str(
value['htmlContent']) + '\n'
f.write(filter_tags(cont))
if start>=total:
return
start = start+10
saveWords(session,gtk,token,start)
去掉没用的标签,网上找的工具类
##过滤HTML中的标签
#将HTML中标签等信息去掉
#@param htmlstr HTML字符串.
def filter_tags(htmlstr):
#先过滤CDATA
re_cdata=re.compile('//]*//\]\]>',re.I) #匹配CDATA
re_script=re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>',re.I)#Script
re_style=re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>',re.I)#style
re_br=re.compile('
')#处理换行
re_h=re.compile('?\w+[^>]*>')#HTML标签
re_comment=re.compile('')#HTML注释
s=re_cdata.sub('',htmlstr)#去掉CDATA
s=re_script.sub('',s) #去掉SCRIPT
s=re_style.sub('',s)#去掉style
s=re_br.sub('\n',s)#将br转换为换行
s=re_h.sub('',s) #去掉HTML 标签
s=re_comment.sub('',s)#去掉HTML注释
#去掉多余的空行
blank_line=re.compile('\n+')
s=blank_line.sub('\n',s)
s=replaceCharEntity(s)#替换实体
return s
##替换常用HTML字符实体.
#使用正常的字符替换HTML中特殊的字符实体.
#你可以添加新的实体字符到CHAR_ENTITIES中,处理更多HTML字符实体.
#@param htmlstr HTML字符串.
def replaceCharEntity(htmlstr):
CHAR_ENTITIES={'nbsp':' ','160':' ',
'lt':'<','60':'<',
'gt':'>','62':'>',
'amp':'&','38':'&',
'quot':'"','34':'"',}
re_charEntity=re.compile(r'?(?P\w+);')
sz=re_charEntity.search(htmlstr)
while sz:
entity=sz.group()#entity全称,如>
key=sz.group('name')#去除&;后entity,如>为gt
try:
htmlstr=re_charEntity.sub(CHAR_ENTITIES[key],htmlstr,1)
sz=re_charEntity.search(htmlstr)
except KeyError:
#以空串代替
htmlstr=re_charEntity.sub('',htmlstr,1)
sz=re_charEntity.search(htmlstr)
return htmlstr
def repalce(s,re_exp,repl_string):
return re_exp.sub(repl_string,s)
效果
最后再贴一下代码地址
代码地址