【python爬虫下载微博图片】

【python爬虫下载微博图片】,第1张

【python爬虫下载微博图片

使用python爬虫下载微博照片【超详解】

所用到的知识

google浏览器抓包requests库爬取当前网页信息从get到的json数据中筛选出url链接及下一个页面的链接二进制文件读写完整的代码

最后一句话

所用到的知识
1.google浏览器抓包
2.requests库爬取当前网页信息
3.从get到的json数据中筛选出url链接及下一个页面的链接
4.二进制文件读写
google浏览器抓包

想要抓取网页中的图片,并动态获取每一个网页的url,需要对网页进行抓包,获取下一个网页的信息。

    使用google浏览器进行抓包 ,于页面中右击鼠标,点击检查,选中network;若需要抓取的部分并不是一次性加载完成,而是滚动到页面下方才再次加载,则说明所需要抓取的部分为ajax动态加载出来的,需要选中XHR部分;抓包工具中:Headers为请求、响应的头信息;payload为获取页面时上传的参数信息()详情见图:

    5.查看多个mymb……的headers、payload、和response之后,我们发现:
    每个header中的requestURL前半部分基本相同,后面的参数部分(id=xxxx,feature=xxxx,page=xxxx)不同,而这一参数部分与payload传递的参数相同。我们可以通过该特点,定制出每一次ajax滚动加载时,所发出请求的url对象。
    payload为每次发出请求时,我们向服务器传递的参数,我们发现,只有page和since_id有不同,且每次的since_id为前一次mymb……请求所获得的response中的sinceid部分。
#url中通用的部分
url = "https://weibo.com/ajax/statuses/mymblog?"

#定制请求头,UV伪装,用于反反爬虫,此处用到coockie是为了绕开登录页面。
headers = {
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
    "cookie":"SINAGLOBAL=5741386286074.814.1642483369215; SCF=AqCdGIDcX3t8lu3S4TsYpjD5EKaGec5GnJl36mGiMtrtoGqa3g10D6TDOiJ1BhaVauiNrBwp3gf5M-YEUbAj8fU.; XSRF-TOKEN=oZVsS72ok2eWD0it4SsAvOt9; SUB=_2AkMWtubMdcPxrARTmPsVz2jibohH-jylY486An7uJhMyAxh77lspqSVutBF-XBrVrpY6r1qBMfNyiRUH5ikru0Jg; SUBP=0033WrSXqPxfM72wWs9jqgMF55529P9D9W5AMzyJMXjcJVpGdW3B5IBj5JpVF020e0eRSKqR1Knf; _s_tentry=weibo.com; Apache=9711553268447.844.1642752620402; ULV=1642752620414:3:3:3:9711553268447.844.1642752620402:1642483825603; WBPSESS=Dt2hbAUaXfkVprjyrAZT_MGDYP6eG158QqpqJOFs8CEwaAA6Br-xrV3MDQOeIjqI5ip8iutNCg_WaAHaQJKuCiY2G9YNQk5NbUxvXReib8RXA1yEFhFflurQ0txrtnzubyjSplQCGXIEnBUQ_LEguw=="
}

#用于存放下一页面的参数:since_id
since_id = [0,0]

#每次对页面发起get请求时所需传递的参数
payload = {
    'uid': '5319635720',
    'page':'1',
    'feature': '0'
}

    #定制每个页面的url,i为页面编号,每次滚动到底部,加载出新页面,i对应加1
    for i in range(1,5):
        print(i)
        if i!=1:
            payload['since_id'] = since_id[i]
            payload["page"] = str(i)
requests库爬取当前网页信息
response = requests.get(url,params=payload,headers=headers).json()

通过抓包工具我们知道,服务器反馈给我们的信息为json格式的,所以此处用.json进行获取。

从get到的json数据中筛选出url链接及下一个页面的链接

在百度搜索json,我们可以得到json格式化工具。或进入链接:json格式化显示工具,将无序的json数据变为可读性较强的数据。
此前,我们通过这段代码,将获取到的json数据进行保存:

    response = requests.get(url,headers=headers).json()
    with open("./photos_of_renwan/weibo.json","w",encoding="utf-8") as fp:
        json.dump(response,fp=fp,ensure_ascii=False)
    print("------当前所有json数据均已下载完毕-----")

然后我们打开我们保存下来从其中一个页面获取到的.json文件,并将其内容复制到json格式化输出工具中,我们得到(此处,我们将json数据看为多个字典以及列表的嵌套):
我们的目的在于,找到我们需要的since_id,以及图片的url,方可推测下一个页面的url参数,以及对图片的url发出get请求,从而下载图片。

于是我们发现,我们所需要的图片的url实际上时存在于以下路径之中的:
data(字典)->list(列表)->每个object的pic_infos(字典)->thumbnail、bmiddle、……、largest中,上述均为字典,里面藏的图片的url不同,从命名就可以看出,largest存储的url为高清图片的url,thumbnail里村的图片url对应的图片是最糊的,这里我们选择largest、->“url”(键值对)中!
于是我们用以下代码进行定位:

        #加载json文件
        data_list=response["data"]["list"]
        since_id.append(response["data"]["since_id"])
        print(since_id)
        #可能存在某个字典元素不是pic_infos,所以采用try—except来接纳keyworderro,使代码可继续运行
        for element in data_list:
            try:
                for val in element["pic_infos"].values():
                    download(val["largest"]["url"])
            except KeyError:
                print("!!keyerro!!") 
        print("------改页面中所有图片均已下载完毕------")

上述代码之中,用到了download函数,对每个url下的图片进行下载。

download函数体见下一部分

二进制文件读写

download函数:

def download(need_download_url):
    pictures = requests.get(url=need_download_url,headers = headers).content
    filename = "./photos_of_renwan/"+need_download_url[29:]
    print("filename:",filename)
    print("------上述文件已下载完成------")
    #图片为二进制文件
    with open(filename,"wb")as fp:
        fp.write(pictures)

图片为二进制文件,故此处用.content进行接受,'wb’格式写入。
filename这边为什么使用了need_download_url的切片?
如不使用切片,我们传递的need_download_url为完整的url,其中含有/符号,可能产生转义,所以我们采用切片,切除这些部分。

完整的代码
import requests
import os
import json

#url中通用的部分
url = "https://weibo.com/ajax/statuses/mymblog?"

#定制请求头,UV伪装,用于反反爬虫
headers = {
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36",
    "cookie":"SINAGLOBAL=5741386286074.814.1642483369215; SCF=AqCdGIDcX3t8lu3S4TsYpjD5EKaGec5GnJl36mGiMtrtoGqa3g10D6TDOiJ1BhaVauiNrBwp3gf5M-YEUbAj8fU.; XSRF-TOKEN=oZVsS72ok2eWD0it4SsAvOt9; SUB=_2AkMWtubMdcPxrARTmPsVz2jibohH-jylY486An7uJhMyAxh77lspqSVutBF-XBrVrpY6r1qBMfNyiRUH5ikru0Jg; SUBP=0033WrSXqPxfM72wWs9jqgMF55529P9D9W5AMzyJMXjcJVpGdW3B5IBj5JpVF020e0eRSKqR1Knf; _s_tentry=weibo.com; Apache=9711553268447.844.1642752620402; ULV=1642752620414:3:3:3:9711553268447.844.1642752620402:1642483825603; WBPSESS=Dt2hbAUaXfkVprjyrAZT_MGDYP6eG158QqpqJOFs8CEwaAA6Br-xrV3MDQOeIjqI5ip8iutNCg_WaAHaQJKuCiY2G9YNQk5NbUxvXReib8RXA1yEFhFflurQ0txrtnzubyjSplQCGXIEnBUQ_LEguw=="
}

#用于存放下一页面的参数:since_id
since_id = [0,0]

#每次对页面发起get请求时所需传递的参数
payload = {
    'uid': '5319635720',
    'page':'1',
    'feature': '0'
}

def download(need_download_url):
    pictures = requests.get(url=need_download_url,headers = headers).content
    filename = "./photos_of_renwan/"+need_download_url[29:]
    print("filename:",filename)
    print("------上述文件已下载完成------")
    #图片为二进制文件
    with open(filename,"wb")as fp:
        fp.write(pictures)

if __name__ == '__main__':
    #定制每个页面的url,i为页面编号,每次滚动到底部,加载出新页面,i对应加1
    for i in range(1,5):
        print(i)
        if i!=1:
            payload['since_id'] = since_id[i]
            payload["page"] = str(i)

    
        #爬取网页中含url在内的所有数据
        print("------payload------")
        print(payload)
        print("------payload------")
        response = requests.get(url,params=payload,headers=headers).json()
        print("------当前所有json数据均已获取完毕-----")
        #加载json文件
        data_list=response["data"]["list"]
        since_id.append(response["data"]["since_id"])
        print(since_id)
        #可能存在某个字典元素不是pic_infos,所以采用try—except来接纳keyworderro,使代码可继续运行
        for element in data_list:
            try:
                for val in element["pic_infos"].values():
                    download(val["largest"]["url"])
            except KeyError:
                print("!!keyerro!!") 
        print("------改页面中所有图片均已下载完毕------")


最后一句话

第一次创作文章,创作到深夜,我也是个小白,第一次掌握这个技术,有点激动!可能还有很多地方没讲明白,如果大家有疑惑,可以在评论区提出,我看到之后会在文章里另开一个板块进行补充。

【本文为原创文章,禁止搬运~】

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5720647.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存