【记录】Python爬虫|爬取空间PC版日志模板
注:2021/7/30做
效果
运行结果
模板中免费的部分
excel已简单处理,可以根据顺序大致找到页码。
一共有43个免费模板,其中39个可用,4个损坏。
损坏的模板
▽ 我以为我捡了个漏
▽ 实际上
小彩蛋
▽ “限时免费”的林丹模板
代码
# author: shandianchengzi
# description: get templates of qq diary, saving as "qq日志模板.xlsx". Result: 43 free, 4 damaged.
# status: complete
import json
import requests
import pandas as pd
import re
from time import sleep
url="https://h5.qzone.qq.com/proxy/domain/mall.qzone.qq.com/cgi-bin/v3/cgi_get_letter_paper"
headers={
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Content-Type': 'application/json; charset=utf-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.56',
}
headers['Cookie']="" #不需要填
params={
'mallIds':'',
'keyWord':'',
'vip':0,
'g_tk':'1002114705',
'pageNum':3,
'pageCount':5,
}
datalist = [] #用来存储爬取的网页信息
byYourself={
'number':5, #一次爬取的个数,建议5个,否则得到的数据会对不上
}
def LoadJson(JSON):
try:
return json.load(JSON)
except:
#找到"({"作为开始标志 和"})"作为结束标志之间的所有信息[jsonp格式]
return json.loads(re.match(".*?({.*}).*",JSON,re.S).group(1))
def AddData(content):
for i in content['data']['items']:
i['name']=i['mall']['name']
i['attr']=i['mall']['attr']
datalist.append(i)
#print(i)
def export_excel(export):
try:
#将字典列表转换为DataFrame
pf = pd.DataFrame(list(export))
#指定生成的Excel表格名称
file_path = pd.ExcelWriter('qq日志模板.xlsx')
#替换空单元格
pf.fillna(' ', inplace=True)
#输出
pf.to_excel(file_path, encoding='utf-8', index=False)
#保存表格
file_path.save()
print('保存成功!')
except Exception as e:
print("[-] Error = "+str(e))
print('无法导出为excel,请检查是否未关闭同名excel文件。正在重试……')
sleep(2)
export_excel(export)
def getData(total):
try:
params['pageCount']=byYourself['number']
pageTotal=int(total/byYourself['number'])+2
print('一共要加载',pageTotal,'页,请耐心等待:')
for i in range(1,pageTotal):
params['pageNum']=i
print('第',i,'页,',end='')
res = requests.get(url, params=params, headers=headers)
content=LoadJson(res.text)
AddData(content)
except Exception as e:
print("[-] Error = "+str(e))
print(res.text)
print(len(datalist))
export_excel(datalist)
def myFunc():
datalist.clear()
res = requests.get(url, params=params, headers=headers)
#找到"({"作为开始标志 和"})"作为结束标志之间的所有信息[jsonp格式]
content=LoadJson(res.text)
total=content['data']['total']
print(total)
getData(total)
myFunc()
问题及解决方式
1. 返回数据_callback({})而非json
这种数据返回格式,使我们无法直接使用json.load(res.text)
解析。
问题根源在于JSONP
这种数据传输格式。
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
比如,可用script标签直接指向不同域下的js脚本,在js脚本中加入这个函数。
本例中的_callback({})
便是JSONP
的典型应用。
解决方式:正则去掉_callback({})
参考https://blog.csdn.net/weixin_38208912/article/details/104208785。
def LoadJson(JSON):
try:
return json.load(JSON)
except:
#找到"({"作为开始标志 和"})"作为结束标志之间的所有信息[jsonp格式]
return json.loads(re.match(".*?({.*}).*",JSON,re.S).group(1))
2. 获取封面图链接
封面图的链接格式:
https://qzonestyle.gtimg.cn/qzone/space_item/pre/14/108942_1.gif
找了一下规律,明显是位置+ id + _1.gif。
可惜https://qzonestyle.gtimg.cn/qzone/space_item/pre/后面的14
不是固定的值,我暂时没有去管它的生成规律,免费的只有39个,全部点一遍都比找出生成规律划算。因此该问题没有解决方案。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix