(二)批量下載百度網站圖片


批量下載百度網站圖片


獲取圖片的url鏈接

首先,打開百度圖片首頁,注意url中的index,將index修改成flip即可把瀑布流頁面切換成傳統翻頁版(flip),這樣有利於觀察不同頁數的url的規律。

對比不同頁數的url可發現:pn參數是請求到的數量。通過修改pn參數來改變頁數。其中gsm參數是pn參數的16進制表達,去掉無妨。%E6%9F%B4%E7%8A%AC為搜索的關鍵詞的轉碼。

(1)第一頁:https://image.baidu.com/search/flip?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1581675184369_R&pv=&ic=&nc=1&z=&hd=&latest=&copyright=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=柴犬
(2)第二頁:https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=柴犬&pn=20&gsm=3c&ct=&ic=0&lm=-1&width=0&height=0
(3)第三頁:https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=柴犬&pn=40&gsm=50&ct=&ic=0&lm=-1&width=0&height=0

因此url的格式為:

https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%s&pn=%d' %(name,i*20)#%s=name %d=i*20

(1) %用法
i.整數輸出
%o —— oct 八進制
%d —— dec 十進制
%x —— hex 十六進制

print('%o' % 20)  # 24
print('%d' % 20)  # 20
print('%x' % 20)  # 14

ii.浮點數輸出
%f ——保留小數點后面六位有效數字

%.3f,保留3位小數位

%e ——保留小數點后面六位有效數字,指數形式輸出

%.3e,保留3位小數位,使用科學計數法

%g ——在保證六位有效數字的前提下,使用小數方式,否則使用科學計數法

%.3g,保留3位有效數字,使用小數或科學計數法

print('%f' % 1.11)  # 默認保留6位小數 1.110000
print('%.1f' % 1.11)  # 取1位小數 1.1
print('%e' % 1.11)  # 默認6位小數,用科學計數法 1.110000e+00
print('%.3e' % 1.11)  # 取3位小數,用科學計數法 1.110e+00
print('%g' % 1111.1111)  # 默認6位有效數字 1111.11
print('%.7g' % 1111.1111)  # 取7位有效數字 1111.111
print('%.2g' % 1111.1111)  # 取2位有效數字,自動轉換為科學計數法 1.1e+03

iii.字符串輸出
%s
%10s——右對齊,占位符10位
%-10s——左對齊,占位符10位
%.2s——截取2位字符串
%10.2s——10位占位符,截取兩位字符串

print('%s' % 'hello world')  # 字符串輸出  hello world
print('%20s' % 'hello world')  # 右對齊,取20位,不夠則補位           hello world
print('%-20s' % 'hello world')  # 左對齊,取20位,不夠則補位 hello world         
print('%.2s' % 'hello world')  # 取2位 he
print('%10.2s' % 'hello world')  # 右對齊,取2位         he
print('%-10.2s' % 'hello world')  # 左對齊,取2位 he     

獲取圖片地址(objURL)

在網頁源代碼中使用搜索objURL觀察代碼再配合正則表達式可得:

results = re.findall(r'\"objURL\":\"(.*?)\", html)

(1)hoverURL 是鼠標移動過后顯示的版本
(2)humbURL,middleURL是圖片縮小的版本
(3)objURL是原圖

代碼框架

獲取圖片url代碼

def getperpage(pn,name,num):#pn指爬取頁數,name指搜索關鍵詞,num=爬取的數量
    for i in range(int(pn)):
        print('正在獲取第{}頁'.format(i + 1))
        url= 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%s&pn=%d' %(name,i*20)#%s=name %d=i*20
        headers = {
            'Connection': 'keep-alive',
            'Cache-Control': 'max-age=0',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36',
            'Sec-Fetch-Dest': 'document',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
            'Sec-Fetch-Site': 'same-origin',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-User': '?1',
            'Referer': 'http://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E7%99%BE%E5%BA%A6',
            'Accept-Language': 'zh-CN,zh;q=0.9',
        }
        response=requests.get(url,headers=headers)
        html=response.content.decode()#區分與response.txt的差別
        results=re.findall(r'\"objURL\":\"(.*?)\"', html)#(.*?)中的括號不能丟失
        #正則表達式解析:"objURL":"http://img.jk51.com/img_jk51/384725631.jpeg" 建議使用網頁源代碼用CTRL+F查詢來觀察,用F12的難以觀察objURL的格式
        save_to_txt(results,name,i,num)

response.text

- 類型:str
- 解碼類型: 根據HTTP 頭部對響應的編碼作出有根據的推測,推測的文本編碼
- 如何修改編碼方式:response.encoding=”gbk”

response.content

- 類型:bytes
- 解碼類型: 沒有指定
- 如何修改編碼方式:response.content.decode(“utf-8”)

獲取網頁源碼的通用方式

- response.content.decode()
- response.content.decode(“GBK”)
#解碼方式可以根據響應頭中找到Content-Type:text/html;charset=utf-8或者網頁源碼中content="text/html;charset=utf-8’'來決定.
- response.text

以上三種方法從前往后嘗試,能夠100%的解決所有網頁解碼的問題

所以:更推薦使用response.content.decode()的方式獲取響應的html頁面

保存圖片到本地

def save_to_txt(results,name,i,num):
   count = 0
   j=1
   root='D:\data\study\python\exercise\picture//'+name
   if not os.path.exists(root):#建立文件路徑
       os.mkdir(root)
   for result in results:
       count += 1
       if count<=num:#設置控制數量程序
           print('正在保存第{}個'.format(j))
           try:
               pic = requests.get(result, timeout=10)
               time.sleep(1)
           except:
               print('當前圖片無法下載')
               j += 1
               continue
           path = root + '/' + name + str(i + 1) + '-' + str(j) + '.jpg'  # 圖片路徑及文件命名
           if not os.path.exists(path):
               with open(path, 'wb')as f:
                   f.write(pic.content)
                   print('文件保存成功')
               j += 1
           else:
               print('文件已存在')

open()


(1)打開文件
file=open("文件名",“讀寫模式”)
(2)操作文件
(3)關閉文件
file.close()

注意事項

使用open方法,文件操作完畢之后必須關閉,否則長期保持對文件的連接狀態,造成內存溢出的現象發生。

with open()

1)打開文件
with open ("文件名",“讀寫模式”) as file: 
(2)操作文件
(3)關閉文件(自動關閉)

主函數代碼

def main():
    name=input('請輸入想要搜索的關鍵詞:')
    pn=eval(input('請輸入爬取的頁數:'))
    num=eval(input('請輸入每頁爬取的圖片數量(每頁最多為60):'))
    getperpage(pn,name,num)
main()

引入庫

import requests
import re
import os
import time

完整源代碼

import requests
import re
import os
import time
def getperpage(pn,name,num):#pn指爬取頁數,name指搜索關鍵詞,num=爬取的數量
    for i in range(int(pn)):
        print('正在獲取第{}頁'.format(i + 1))
        url= 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%s&pn=%d' %(name,i*20)#%s=name %d=i*20
        headers = {
            'Connection': 'keep-alive',
            'Cache-Control': 'max-age=0',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36',
            'Sec-Fetch-Dest': 'document',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
            'Sec-Fetch-Site': 'same-origin',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-User': '?1',
            'Referer': 'http://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E7%99%BE%E5%BA%A6',
            'Accept-Language': 'zh-CN,zh;q=0.9',
        }
        response=requests.get(url,headers=headers)
        html=response.content.decode()#區分與response.txt的差別
        results=re.findall(r'\"objURL\":\"(.*?)\"', html)#(.*?)中的括號不能丟失
        #正則表達式解析:"objURL":"http://img.jk51.com/img_jk51/384725631.jpeg" 建議使用網頁源代碼用CTRL+F查詢來觀察,用F12的難以觀察objURL的格式
        save_to_txt(results,name,i,num)

def save_to_txt(results,name,i,num):
    count = 0
    j=1
    root='D:\data\study\python\exercise\picture//'+name
    if not os.path.exists(root):#建立文件路徑
        os.mkdir(root)
    for result in results:
        count += 1
        if count<=num:#設置控制數量程序
            print('正在保存第{}個'.format(j))
            try:
                pic = requests.get(result, timeout=10)
                time.sleep(1)
            except:
                print('當前圖片無法下載')
                j += 1
                continue
            path = root + '/' + name + str(i + 1) + '-' + str(j) + '.jpg'  # 圖片路徑及文件命名
            if not os.path.exists(path):
                with open(path, 'wb')as f:
                    f.write(pic.content)
                    f.close()
                    print('文件保存成功')
                j += 1
            else:
                print('文件已存在')





def main():
    name=input('請輸入想要搜索的關鍵詞:')
    pn=eval(input('請輸入爬取的頁數:'))
    num=eval(input('請輸入每頁爬取的圖片數量(每頁最多為60):'))
    getperpage(pn,name,num)
main()





實例效果展示


參考

[1] https://www.cnblogs.com/Qqun821460695/p/12067699.html
[2]《Python網絡爬蟲與信息提取》http://www.icourse163.org/course/BIT-1001870001
[3] 格式化輸出(%用法和fomat用法) https://www.cnblogs.com/felixwang2/p/9583522.html
[4] open()和with open()的區別 https://www.cnblogs.com/yangzhe0617/p/11038723.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM