麻花痒 发表于 2022-11-1 21:47:13

【记录】Python爬虫|爬取空间PC版日志模板

目录

[*]效果

[*]运行结果
[*]模板中免费的部分

[*]损坏的模板

[*]小彩蛋

[*]代码
[*]问题及解决方式

[*]1. 返回数据_callback({})而非json
[*]2. 获取封面图链接


注:2021/7/30做
效果

运行结果

https://img-blog.csdnimg.cn/c4519cbb24034c69b6592447482abb64.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2MTA2Mjg1,size_16,color_FFFFFF,t_70
模板中免费的部分

https://img-blog.csdnimg.cn/f8c78e4eaf294111900a3b31f63a4d22.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2MTA2Mjg1,size_16,color_FFFFFF,t_70
excel已简单处理,可以根据顺序大致找到页码。
一共有43个免费模板,其中39个可用,4个损坏。
损坏的模板

▽ 我以为我捡了个漏
https://img-blog.csdnimg.cn/b99c8c6d9add4e62a12575b2438441b8.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2MTA2Mjg1,size_16,color_FFFFFF,t_70
▽ 实际上
https://img-blog.csdnimg.cn/bb248a70d94f480b955737618b3e2569.png
小彩蛋

▽ “限时免费”的林丹模板
https://img-blog.csdnimg.cn/91e337cc1ece45c7bef39e2ec154ad6e.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2MTA2Mjg1,size_16,color_FFFFFF,t_70
代码

# 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:
      #找到"({"作为开始标志 和"})"作为结束标志之间的所有信息
      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)
    #找到"({"作为开始标志 和"})"作为结束标志之间的所有信息
    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:
      #找到"({"作为开始标志 和"})"作为结束标志之间的所有信息
      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个,全部点一遍都比找出生成规律划算。因此该问题没有解决方案。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 【记录】Python爬虫|爬取空间PC版日志模板