最近迷上了@桐谷美玲_MireiKiritani小姐姐的顏值,因而在Ins上也關注了一波,因而發現了一大波美圖,但是ins出於版權方面的考慮並不在客戶端和網頁端直接提供圖片的下載功能,因爲以前學習python的最初階段就學過爬蟲,因而重操舊業打起了爬取美圖的打算,也算是對python的一點複習吧。html
移動端操做不便,並且學校IPV6網絡設置好hosts就能輕鬆訪問ins(雖然有時候不太穩定,不過這幾天好像還能夠=,=),首選經過PC端網頁爬取。前端
用Chrome打開ins以後按F12就能進入開發模式,選取上面的圖片就能找到相應的圖片入口,但打開相應的div能夠發如今當前頁面下的圖片全都是縮略圖,所能得到的最大分辨率僅爲640*640。這顯然不能達到要求(`・ω・´),因而我開始找原圖的URL。python
還有一個問題就是ins上面的圖片所有都是使用js動態生成的,也就意味着咱們在使用requests模塊get到的內容僅僅是網頁框架和一堆js腳本而已,對網頁上的network進行監聽就能看到js進行的xmlhttp requests.咱們甚至可以在xmlhttp requests中找到原始圖片的URL,但問題就是這個xmlhttp requests在向服務器發送請求時須要一個Query String,裏面有一串須要隨機生成的variable。能夠經過查找頁面的js代碼找到這串key的生成代碼,但對於很久沒用js的我來講這段js代碼無異於天書,感受看懂須要把前端的知識好好複習複習。在這裏我顯然並無這樣的打算。web
頁面xmlhttp-request加載chrome
js中variable生成的部分代碼瀏覽器
咱們彷佛須要找到一個更可行的方法來得到ins上原始圖片的URL,而這個方法就在這個頁面上。咱們能夠點開每一張圖片從而到達圖片詳情頁,而在詳情頁裏面天然就有咱們所須要的原圖URL。並且幸運的是在圖片詳情頁的html中,咱們能夠直接使用requests得到這個url!服務器
咱們須要下載圖片就須要得到每張圖片的URL,通過前面的討論我已經大體肯定了URL獲取方式:cookie
ins我的主頁 --> ins圖片詳情頁URL --> ins圖片詳情頁 -->詳情頁中的原圖URL網絡
就像前面說到過的,ins我的主頁上的圖片是經過js動態生成的,這就意味着咱們沒有辦法經過requests簡單的得到全部所需的URL,這時候對於並不精通js相關的我來講也就只剩下selenium模擬瀏覽器這一條路了。關於selenium我在這裏也不想多說,以前我也使用過,不過並不熟,配合着文檔和Google也就能實現本身所須要的功能了。併發
整個技術思路就是經過selenium模擬瀏覽器行爲得到ins我的主頁上面關於全部圖片詳情頁的URL,而後經過URL使用requests得到全部詳情頁的HTML,最後經過html解析模塊得到相應原始圖片url,最後直接使用requests下載圖片。
很久沒寫Python和爬蟲了,雖然大體過程仍是有數,但作起來仍是須要邊測試邊搜索文檔,這裏因爲selenium與chrome的加入,對於一些設計網絡和程序控制方面的東西仍是須要本身嘗試。
import requests import time import os from lxml import etree from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains options = webdriver.ChromeOptions() options.add_argument('lang=zh_CN.UTF-8') driver = webdriver.Chrome(chrome_options = options) target = "https://www.instagram.com/mirei_kiritani_/" url_set = set([]) driver.get(target) url_set=set([])#set用來unique URL pic_index = 0 url_set_size = 0 save_dir = './pic/' if not os.path.exists(save_dir): os.mkdir(save_dir) header = { #requests header最好設置一下,不然服務器可能會拒絕訪問 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-US;q=0.7', 'cookie': 'shbid=4419; rur=PRN; mcd=3; mid=W1E7cAALAAES6GY5Dyuvmzfbywic; csrftoken=uVspLzRYlxjToqSoTlf09JVaA9thPkD0; urlgen="{\"time\": 1532050288\054 \"2001:da8:e000:1618:e4b8:8a3d:8932:2621\": 23910\054 \"2001:da8:e000:1618:6c15:ccda:34b8:5dc8\": 23910}:1fgVTv:SfLAhpEZmvEcJn0037FXFMLJr0Y"', 'referer': 'https://www.instagram.com/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36', } while(True): divs = driver.find_elements_by_class_name('v1Nh3') #這裏最好使用xxxx_by_class_name,我嘗試過用xpath絕對路徑,可是好像對於頁面變化比較敏感 for u in divs: url_set.add(u.find_element_by_tag_name('a').get_attribute('href')) if len(url_set) == url_set_size: #若是本次頁面更新沒有加入新的URL則可視爲到達頁面底端,跳出 break url_set_size = len(url_set) ActionChains(driver).send_keys(Keys.PAGE_DOWN).perform()#三次滑動,保證頁面更新足夠 ActionChains(driver).send_keys(Keys.PAGE_DOWN).perform() ActionChains(driver).send_keys(Keys.PAGE_DOWN).perform() time.sleep(3) #下載圖片: def pic_download(u_download): global pic_index rec = requests.get(u_download, headers = header) selector = etree.HTML(rec.content) meta = selector.xpath('/html/head/meta[10]')[0] #使用xpath解析頁面 real_pic_url = meta.get("content").strip() pic_extend = real_pic_url[-4:] file_name = save_dir + "mirei_" + str(pic_index) + pic_extend pic_index += 1 f = open(file_name,'wb') pic_bin = requests.get(real_pic_url).content f.write(pic_bin) f.close() for url_ in url_set: pic_download(url_)
主要仍是在控制chrome滑動窗口的時候須要對滑動次數和頁面HTML更新速度進行微調,不然會出現selenium無法獲取頁面變化的問題。還有就是在獲取url的時候最好保持chrome在前臺運行(反正不能最小化,可能沒法PAGEDOWN?),不然會出問題。
最後想說的就是這只是一個最簡陋的爬蟲,後續在下載,解析過程當中有不少能夠優化的地方,好比並發下載,selenium設置優化等等,這裏我就不深刻了。
附上下載後的美圖(づ ̄3 ̄)づ╭❤~
http://selenium-python-zh.readthedocs.io/en/latest/locating-elements.html
https://blog.csdn.net/lb245557472/article/details/79978374