額,明明記得昨晚存了草稿箱,一覺醒來沒了,那就簡寫點(實際上是具體怎麼解釋我也不太懂/xk,純屬我的理解,有錯誤還望指正)python
環境:json
版本:python3api
IDE:pycharm2017.3.3瀏覽器
瀏覽器:火狐(瀏覽器建議火狐,Chrome)網絡
爬取網站:堆糖app
選堆糖是由於比較好爬取(除了img文件就是xhr文件),別網站的反爬取對我這個水平來講都太心機了工具
安裝配置什麼的以前都寫過,這裏就不提了,直接開始網站
1.先來瀏覽一下這個網站,打開堆糖官網,搜索校花,他就會給咱們推薦一些圖片,當咱們滾動到頁面底部時,他又會加載新的一些圖片,再滾到底,再加載,這樣加載了五次,才把第一頁的全部圖片加載出來(這裏體現了這個網站的防爬,不過也好破)ui
咱們的目標就是把這19頁,每頁的圖片都爬下來編碼
2.從新搜索一下關鍵字,咱們先不往下滾動,右鍵查看元素,選擇網絡,能夠看到目前這一頁中加載的圖片,
3.而後咱們把頁面往下滾動,讓他繼續加載,同時咱們觀察者網絡這個窗口,全部請求的圖片也都顯示在這裏,這時發現xhr類型的文件,這樣的文件一共有五個,也就是同一頁面中每次滾動到頁面底部,新加載圖片時就會出現這樣的文件
4.主要關注一下這個文件,把窗口切換到xhr類型下,雙擊打開其中的一個
5.這個請求網址使咱們須要的,複製到地址欄中
6.這裏打開若是是全部代碼堆在一塊兒的那樣,就須要在線解析一下,解析工具 將地址複製進去進行校驗
而我這裏的火狐瀏覽器打開直接就是轉換好的
其中的path就是咱們須要的
而這個limit就是限制咱們爬取數量的參數,後面須要修改這個參數來爬取所有圖片
7.對請求地址進行分析
https://www.duitang.com/napi/blog/list/by_search/?kw=校花&type=feed&include_fields=top_comments,is_root,source_link,item,buyable,root_id,status,like_count,sender,album&_type=&start=24&_=1520036797589
將沒用的刪掉
https://www.duitang.com/napi/blog/list/by_search/?kw=校花&start=24
修改參數start(從0開始爬取),添加參數limit(上限),格式都是&開頭
https://www.duitang.com/napi/blog/list/by_search/?kw=校花&start=0&limit=1000
以上就是爬取的分析過程,代碼以下
1 import requests 2 import threading 3 import urllib.parse 4 5 #設置最大線程 開啓10個線程就鎖住 6 thread_lock = threading.BoundedSemaphore(value=10) 7 8 9 'https://www.duitang.com/napi/blog/list/by_search/?kw=%E6%A0%A1%E8%8A%B1&start=0&limt=1000' 10 #經過url 獲取數據 11 #單個頁面 12 def get_page(url): 13 #requests.get 自帶了json.loads 14 page = requests.get(url) 15 #提取須要的content 16 page = page.content 17 # 將bytes轉成 字符串 18 page = page.decode('utf-8') 19 return page 20 21 #label爲關鍵字 22 #取全部頁面pages的連接 23 def pages_from_duitang(label): 24 pages = [] 25 url = 'https://www.duitang.com/napi/blog/list/by_search/?kw={}&start={}&limt=1000' 26 #將中文轉成url編碼 27 label = urllib.parse.quote(label) 28 for index in range(0, 3600, 50): 29 #將這兩個變量替換佔位符{} 30 u = url.format(label,index) 31 page = get_page(u) 32 pages.append(page) 33 return pages 34 35 36 # print(get_page('https://www.duitang.com/napi/blog/list/by_search/?kw=%E6%A0%A1%E8%8A%B1&start=0&limt=1000')) 37 #page是get_page()返回的頁面信息 38 #startpart和endpart是邊界條件,兩個給定的字符串 39 # 單個頁面的對象,startpart 所要匹配字符1,匹配的字符2 40 def findall_in_page(page,startpart,endpart): 41 all_strings = [] 42 end = 0 43 # 從end這個字符串開始找,找startpart 44 # .find()!=-1說明找到該字符串,返回的是該字符串的起始下標 45 while page.find(startpart,end) != -1: 46 # 須要的圖片的連接的起始位置start 47 start = page.find(startpart, end)+len(startpart) 48 # 從起始字符串開始找結束字符串 49 end = page.find(endpart,start) 50 #切片 取兩個所要匹配字符 之間的部分也就是圖片url 51 string = page[start:end] 52 #存入列表 53 all_strings.append(string) 54 return all_strings 55 56 # "path": "https://b-ssl.duitang.com/uploads/item/201708/20/20170820215827_fa483.jpeg" 57 def pic_urls_from_pages(pages): 58 pic_urls = [] 59 for page in pages: 60 # 處理一個頁面 61 urls = findall_in_page(page,'path":"','"') 62 pic_urls.extend(urls) # 合併列表 63 return pic_urls 64 65 def download_pics(url, n): 66 r = requests.get(url) 67 path = '../pics' + str(n) + '.jpg' 68 with open(path,'wb') as f: 69 f.write(r.content) 70 #下載完了,解鎖 71 thread_lock.release() 72 73 def main(label): 74 pages = pages_from_duitang(label) 75 pic_urls = pic_urls_from_pages(pages) 76 77 n = 0 78 for url in pic_urls: 79 n += 1 80 print('正在下載第{}張圖片'.format(n)) 81 82 #上鎖 83 thread_lock.acquire() 84 #下載 這個方法丟進線程池 85 t = threading.Thread(target=download_pics,args=(url,n)) 86 t.start() 87 88 89 main('校花')
運行結果
不一樣的網站防爬不同,但思路應該都差很少