所用到的知识
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("------改页面中所有图片均已下载完毕------")最后一句话
第一次创作文章,创作到深夜,我也是个小白,第一次掌握这个技术,有点激动!可能还有很多地方没讲明白,如果大家有疑惑,可以在评论区提出,我看到之后会在文章里另开一个板块进行补充。
【本文为原创文章,禁止搬运~】
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)