(非)正確的姿勢擷取收藏的p站插畫_python

來源:互聯網
上載者:User
前面的前面

菜鳥一隻蒟蒻一枚輕噴勿嘲 BG

並沒有bg,強行搞一個 正題

亂搞哪來正題一說。
電腦室是7-24開著的,想著用來扒一些東西
然後在我逛p站的時候突然想起來自己三位元的收藏圖片是不是可以抓下來呢。
寫了兩個無作業的晚上, ps:

p站的頻繁異常登入是會反饋給郵箱的,小心郵箱被刷成999+ 登入

這是瀏覽器F12登入時可以看到的,為了不使跳轉後清空我們需要勾上Preserve Log

可以看到這裡除了登陸的帳號密碼還有一個類似驗證的東西postkey
翻網頁原始碼可以看到

<input type="hidden" name="post_key" value="cb02a4460fd7a41fb46d0129e4ca5ece">

訪問pixiv是要一個Referer的(不會翻譯),根據個人理解,它代表的是跳轉前的網址是什麼
這個東西一定要有是蠻重要的不然訪問不到原圖片的 收藏列表

首先是收藏的網址

為了讓爬蟲更像爬蟲,我們要在每個頁面中尋找帶有next類的標籤

<span class="next"><a href="?rest=show&amp;p=2" rel="next" class="_button" title="下一頁">

這樣一個東西,裡面的a就指向下一頁了
如果找不到下一頁,那就是抓到底了 圖片

每一頁的圖片有很多不同解析度的地址,以id為59345668的圖片來說,原圖片在這一行裡面

<img alt="君の名は。" width="780" height="1103" data-src="http://i1.pixiv.net/img-original/img/2016/10/07/01/26/24/59345668_p0.png" class="original-image">

就是這張

於是正則匹配一下就搞出來了,需要注意的是這樣的一條漫畫是沒有的

對於一張圖片有兩種方式儲存 1.

urllib.urlretrieve(url, path, rollFunc)#url是圖片地址,path是本地目錄,那個rollFunc是yy出來的表示下載進度的東西

也就是之前爬百度貼吧用到過的 2.

with open(path, 'wb) as file:    file.write(requests.get(url).content)#url同上,path同上,w是寫b是以二進位方式

這裡只用了第二種方法因為快啊 多線程

怎麼樣是不是很高大上對不對很興奮對不對
對於數量級的任務顯然我們是可以讓他們平行處理的,速度提升很顯然
為了方便我直接跳過了Thread因為threading更好用
看代碼

def cal(a, b):    print a + bjobs = []for p in xrange(50):    jobs.append(threading.Thread(target = cal, args = (1, 2)))for job in jobs:    job.start()for job in jobs:    job.join()

這裡先定義了一個list用來記錄所有的線程,然後是封裝
target是需要調用的函數(顯然)args是調用參數(還是顯然),args必須是一個tuple
start()和join()分別是開始和等待,保證所有的都線程結束

那麼最終的大概流程就有了
登入1->找到收藏頁的圖片並把下載任務裝進線程->跑一遍->找下一頁的超連結->回到1 字串

過去寫pascal、c++都是直接stra = strb + strc,後面到了python這樣就效率及其低下了
究其原因,在python中string是不可變的,那麼每一次的+運算都要重新開產生個string
又是查網頁,找到解決方案

stra = ''.join(strb, strc)
Code

頭一次寫著麼長的東西,寫寫停停用了幾個晚上。還是很有成就感的 (即使代碼很醜)

import threadingimport requestsimport osimport redef getPage(html, url, headers):    while 1:        try:            page = html.get(url, headers = headers, timeout = 3).content            break        except Exception, e:            print e            pass    return pagedef logIn(html, url, headers, data):    while 1:        try:            html.post(url, headers = headers, data = data, timeout = 2)            return        except Exception, e:            print e            passdef get(html, url, headers, index, filepath):    headers['Referer'] = url    page = ''    while 1:        try:            page = html.get(url, headers = headers, timeout = 3).content            break        except Exception, e:            print e            pass    reg = re.compile(r'<img alt=".+?" width="\d+" height="\d+" data-src="(.+?)"')    picUrl = re.findall(reg, page)    if len(picUrl) == 0:        return    picUrl = picUrl[0]    print picUrl    if os.path.exists(r'%s%s%s' %(filepath, str(index), picUrl[-4:])):        return    headers['Referer'] = picUrl    while 1:        try:            page = html.get(picUrl, headers = headers, timeout = 3).content            break        except Exception, e:            pass    with open(r'%s%s%s' %(filepath, str(index), picUrl[-4:]), 'wb') as file:        file.write(page)    print index    print r'%s%s%s' %(filepath, str(index), picUrl[-4:])html = requests.Session()preUrl = 'http://www.pixiv.net/member_illust.php?mode=medium&illust_id='logInUrl = 'https://accounts.pixiv.net/login?return_to=0&lang=zh&source=pc&view_type=page'prefavUrl = 'http://www.pixiv.net/bookmark.php'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0'}data = {'return_to': 'http://www.pixiv.net/'}pixivId = raw_input('pixiv id:')password = raw_input('password:')filepath = raw_input('filepath:')data['pixiv_id'] = pixivIddata['password'] = passwordheaders['Referer'] = logInUrllogInPage = getPage(html, logInUrl, headers)reg = re.compile(r'<input type="hidden" name="post_key" value="(.+?)">')postKey = re.findall(reg, logInPage)[0]data['post_key'] = postKeylogIn(html, logInUrl, headers, data)favUrl = prefavUrlindex = 0while 1:    headers['Referer'] = favUrl    favPage = getPage(html, favUrl, headers)    reg = re.compile(r'"data-type="illust"data-id="(\d+)"data-tags=')    lis = re.findall(reg, favPage)    jobs = []    for p in lis:        url = ''.join([preUrl, p])        index += 1        jobs.append(threading.Thread(target = get, args = (html, url, headers, index, filepath)))    for job in jobs:        job.start()    for job in jobs:        job.join()    reg = re.compile(r'class="next"><a href="(.+?)"')    bacUrl = re.findall(reg, favPage)    if bacUrl:        p = re.sub('&amp;', '&', bacUrl[0])        favUrl = prefavUrl + p        print favUrl    else:        break

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.