爬虫之数据解析

发布于:2024-10-16 ⋅ 阅读:(12) ⋅ 点赞:(0)

数据解析

数据解析这篇内容, 很多知识涉及到的都是以前学习过的内容了, 那这篇文章我们主要以实操为主, 来展开来讲解关于数据解析的内容。

360搜索图片

在这里插入图片描述

请求的url大家不需要再找了, 相信大家都会找请求了, 寻找请求从我的第一篇爬虫的博客开始到现在一直都在写,这边的话, 我已经给大家找好请求的url了, 请求的url是https://image.so.com/j?callback=jQuery1830016941744487520394_1728302031468&q=%E8%A1%A8%E6%83%85%E5%8C%85&qtag=&pd=1&pn=60&correct=%E8%A1%A8%E6%83%85%E5%8C%85&adstar=0&tab=all&sid=0ba46b6797934a87fe2a080f1319d622&ras=6&cn=0&gn=0&kn=26&crn=0&bxn=20&cuben=0&pornn=0&manun=50&src=360pic_strong&sn=106&ps=150&pc=150&_=1728302047538

import requests
import re
import json
import os

url = 'https://image.so.com/j?callback=jQuery1830016941744487520394_1728302031468&q=%E8%A1%A8%E6%83%85%E5%8C%85&qtag=&pd=1&pn=60&correct=%E8%A1%A8%E6%83%85%E5%8C%85&adstar=0&tab=all&sid=0ba46b6797934a87fe2a080f1319d622&ras=6&cn=0&gn=0&kn=26&crn=0&bxn=20&cuben=0&pornn=0&manun=50&src=360pic_strong&sn=106&ps=150&pc=150&_=1728302047538'
res = requests.get(url)
print(res.json())

结果:

在这里插入图片描述

报错了, 这个报错的原因很简单, 就是在最后一样的print(res.json())这里出的问题。

我们只需要把json()改为text即可, 因为后端数据返回的不完全是一个字典或列表, 所以只能用text.

修改后代码:

import requests
import re
import json
import os![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/658db3e5a12a47bdb5afecb1d9f969e2.png)


url = 'https://image.so.com/j?callback=jQuery1830016941744487520394_1728302031468&q=%E8%A1%A8%E6%83%85%E5%8C%85&qtag=&pd=1&pn=60&correct=%E8%A1%A8%E6%83%85%E5%8C%85&adstar=0&tab=all&sid=0ba46b6797934a87fe2a080f1319d622&ras=6&cn=0&gn=0&kn=26&crn=0&bxn=20&cuben=0&pornn=0&manun=50&src=360pic_strong&sn=106&ps=150&pc=150&_=1728302047538'
res = requests.get(url)
print(res.text)

返回结果:

在这里插入图片描述

在最前面有个jQuery1830016941744487520394_1728302031468, 然后我们想要的数据是在小括号里面的那个字典。

那我们怎么去获取到小括号里面的数据呢?

如果大家看过我以前写过的博客的话,应该有印象, 就是之前有个实战题目里面也有类似于这种的情况, 上次那个实战内容就是爬取关于股票数据的内容。上次的解决办法是把url里面的callback=xxxx那一串去掉。

那今天我们这篇文章会讲解第二种方法, 不删除那串callback=xxxx也一样能够实现。

说明一下讲第二种方法的原因:

1.上次博客实战题里面用到的方法不一定都可行(有时候可行, 看运气), 并不是所有请求, 去掉那个参数就可以拿到自己想要的数据。

2.这里要讲的第二种方法, 就是解决提取我们想要的数据, 并且没有任何的运气成分, 这种办法可以解决一切有关于这一类的问题。

一、

字符串替换

import requests
import re
import json
import os

url = 'https://image.so.com/j?callback=jQuery1830016941744487520394_1728302031468&q=%E8%A1%A8%E6%83%85%E5%8C%85&qtag=&pd=1&pn=60&correct=%E8%A1%A8%E6%83%85%E5%8C%85&adstar=0&tab=all&sid=0ba46b6797934a87fe2a080f1319d622&ras=6&cn=0&gn=0&kn=26&crn=0&bxn=20&cuben=0&pornn=0&manun=50&src=360pic_strong&sn=106&ps=150&pc=150&_=1728302047538'
res = requests.get(url)
print(res.text)
res_data = res.text
t_str = res_data.replace("jQuery1830016941744487520394_1728302031468(", "").replace(")", "")

这种方法, 简单粗暴, 我们没有在请求的url里面删除callback参数, 而是用字符串的替换方法来对返回的数据进行处理。

但是这也有局限性, 原因很简单, 因为jQuery后面的那串数字会随时变化的, 当那些数字发生改变的时候, 那我们不得又再去把请求里面的这个jQueryxxxxxx这块地方再放到replace里面去替换么, 这样岂不是太麻烦了!!!

所以我们还有一钟办法, 就是用正则表达式去匹配我们想要的内容(正则表达式是python的基础内容, 如果对这方面还不熟悉的话, 需要去学习一下python编程基础部分)。

二、

正则表达式

import requests
import re
import json
import os

url = 'https://image.so.com/j?callback=jQuery1830016941744487520394_1728302031468&q=%E8%A1%A8%E6%83%85%E5%8C%85&qtag=&pd=1&pn=60&correct=%E8%A1%A8%E6%83%85%E5%8C%85&adstar=0&tab=all&sid=0ba46b6797934a87fe2a080f1319d622&ras=6&cn=0&gn=0&kn=26&crn=0&bxn=20&cuben=0&pornn=0&manun=50&src=360pic_strong&sn=106&ps=150&pc=150&_=1728302047538'
res = requests.get(url)
print(res.text)
res_data = res.text
t_str = re.findall('jQuery\d+_\d+\((.*?)\);',res_data)[0] #获取到的数据 {xxx}

我们想要获取到小括号里面的那个字典, 在正则表达式里面, 我们只需要输入.*?即可。

json字符串和对象数据互转方法:

json字符串->对象数据: loads方法

对象数据->json字符串: dumps方法

爬取360里面的图片完整代码:

那在我们这个爬取360里面的图片的这个案例中, 我们看一看是怎么实现的

url = 'https://image.so.com/j?callback=jQuery1830016941744487520394_1728302031468&q=%E8%A1%A8%E6%83%85%E5%8C%85&qtag=&pd=1&pn=60&correct=%E8%A1%A8%E6%83%85%E5%8C%85&adstar=0&tab=all&sid=0ba46b6797934a87fe2a080f1319d622&ras=6&cn=0&gn=0&kn=26&crn=0&bxn=20&cuben=0&pornn=0&manun=50&src=360pic_strong&sn=106&ps=150&pc=150&_=1728302047538'

import requests
import re
import json
import os
res = requests.get(url)

# print(res.json())
res_data = res.text
print(res_data)
# 如果以后看到这种响应数据, 可以尝试去除参数中的callback,如果没法去掉,如何解决?
# jQuery1830016941744487520394_1728302031468({});
# 1- 字符串替换
# 2- 正则提取
t_str = re.findall('jQuery\d+_\d+\((.*?)\);',res_data)[0] #{xxx}
# print(type(t_str))
# print(t_str)
# 通过正则提取,提取到的数据是一个规范的数据,但是是个字符串类型,不好循环取值
# 如果是个字典, 那就很方便了
# 字符串 转为 字典?
# json字符串 转为 字典?

t_dict = json.loads(t_str)
# print(t_dict,type(t_dict))

d_path = '360图片'
# 如果能找到,则为True,反之则False
if not os.path.exists(d_path):
    # 创建
    os.mkdir(d_path)
count = 0
p = 0
for i in t_dict['list']:
    print(p)
    p+=1
    # 图片的url
    img_url = i['_thumb']

#    对img_url发起请求
    img_res = requests.get(img_url)
#   保存图片  (保存图片数据)
#     文件名必须要变,如果不变,最后只会生成一张图片
#     获取图片的名字
    name = i['title']
    # 判断名字中是否包含/
    # if '/' in name :
    #     # 则替换 替换到重新赋值,字符串是不可变
    #     name = name.replace('/','')
    # 如果图片是静图,后缀名可以是jpg或者png
    # 如果图片是动图,后缀名可以是gif
    suffix = img_url.split('.')[-1]
    # 新发型小熊猫表情包.jpg
    # 如果路径为f'{name}.{suffix}' 那么会把所有的图片文件创建在当前python文件对应的文件夹中
    # 如果路径为f'360图片/{name}.{suffix}' 360图片文件夹必须要先提前创建
    # 创建的方式:1-手动自己创建 2-代码创建
    # try:
    with open(f'{d_path}/{count}.{suffix}', 'wb')as f:
        f.write(img_res.content)
    print(f'{img_url}{name}{count}已经下载完毕~')
    count += 1
    # except Exception as e:
    #     print(e)
    #     # 如果图片的原本名字出现特殊符号导致保存失败
    #     # 处理异常,名字改为数字
    #     with open(f'{d_path}/{count}.{suffix}', 'wb')as f:
    #         f.write(img_res.content)
    #     count+=1
    #     print(f'{img_url}{count}已经下载完毕~')

解释代码:

  1. t_dict = json.loads(t_str)这句话是将json字符串转换为字典。

  2. os库, 这个库是用于与操作系统进行交互。if not os.path.exists(d_path)这句话在判断是否有这么个文件夹(目录), 如果没有就创建, exists的返回值取决于该文件夹(目录)是否存在, 存在为true, 不存在为false。

  3. 对img_url发起请求: img_res = requests.get(img_url), 获取图片的名字: name = i[‘title’], 文件名后缀: suffix = img_url.split(‘.’)[-1]。

  4. 最后下载图片并保存:

     with open(f'{d_path}/{count}.{suffix}', 'wb')as f:
            f.write(img_res.content)
        print(f'{img_url}{name}{count}已经下载完毕~')
        count += 1
    

结果:

在这里插入图片描述

再打开图片看看:

在这里插入图片描述

360搜索图片, 然后爬取图片成功!!!

实战:

爬取百度图片

百度搜索任意主题图片进行下载

先自己尝试做一做哦, 不要马上看答案哦!!!

还有, url请求是根据你在搜索框里面搜索的内容给你跳出来的网页图片来决定的, 每个人爬取的内容不一样, 那每个人的请求url就会不一样, 请求url自己去寻找。

参考答案:

import requests
import os


def download_pic(i, url):
    res = requests.get(url)
    if not os.path.exists("picture"):
        os.mkdir("picture")
    with open('picture/beautiful_girl'+str(i)+'.jpg', 'wb') as f:
        f.write(res.content)
        print('The picture is already fetched about beautiful_girl'+str(i)+'.jpg')


url = "https://image.baidu.com/search/acjson?tn=resultjson_com&logid=8411016515474874704&ipn=rj&ct=201326592&is=&fp=result&fr=&word=%E7%BE%8E%E5%A5%B3&cg=girl&queryWord=%E7%BE%8E%E5%A5%B3&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=0&ic=0&hd=0&latest=0&copyright=0&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn=0&rn=30"
headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
    "referer": "https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=&pv=&ic=0&nc=1&z=0&hd=0&latest=0&copyright=0&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&dyTabStr=MCwzLDEsMiwxMyw3LDYsNSwxMiw5&ie=utf-8&ctd=&sid=&word=%E7%BE%8E%E5%A5%B3"
}
response = requests.get(url, headers=headers)
# print(response.json())
res_data = response.json()
c = 1
for i in res_data['data']:
    if i != {}:
        print(i['thumbURL'])
        download_pic(c, i['thumbURL'])
        c += 1

结果:

在这里插入图片描述

在这里插入图片描述

这道实战题, 你写出来了吗? 如果写出来的话, 给自己鼓掌哦👏

以上就是爬虫数据解析的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!
如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.
学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.
人生路漫漫, 白鹭常相伴!!!