(非)正确的姿势获取收藏的p站插画_python

前面的前面


菜鸟一只蒟蒻一枚轻喷勿嘲

BG


并没有bg,强行搞一个

正题


乱搞哪来正题一说?
电脑室是7-24开着的,想着用来扒一些东西
然后在我逛p站的时候突然想起来自己三位数的收藏图片是不是可以抓下来呢?
写了两个无作业的晚上,

ps:

p站的频繁异常登录是会反馈给邮箱的,小心邮箱被刷成999+

登录


这是浏览器F12登录时可以看到的,为了不使跳转后清空我们需要勾上Preserve Log
(非)正确的姿势获取收藏的p站插画_python_第1张图片
可以看到这里除了登陆的帐号密码还有一个类似验证的东西postkey
翻网页源代码可以看到

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

访问pixiv是要一个Referer的(不会翻译),根据个人理解,它代表的是跳转前的网址是什么
这个东西一定要有是蛮重要的不然访问不到原图片的

收藏列表


首先是收藏的网址
这里写图片描述
为了让爬虫更像爬虫,我们要在每个页面中寻找带有next类的标签

<span class="next"><a href="?rest=show&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 + b

jobs = []

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 threading
import requests
import os
import re

def getPage(html, url, headers):
    while 1:
        try:
            page = html.get(url, headers = headers, timeout = 3).content
            break
        except Exception, e:
            print e
            pass
    return page

def logIn(html, url, headers, data):
    while 1:
        try:
            html.post(url, headers = headers, data = data, timeout = 2)
            return
        except Exception, e:
            print e
            pass

def 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'.+?)
    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'] = pixivId
data['password'] = password

headers['Referer'] = logInUrl
logInPage = getPage(html, logInUrl, headers)
reg = re.compile(r'')
postKey = re.findall(reg, logInPage)[0]
data['post_key'] = postKey

logIn(html, logInUrl, headers, data)
favUrl = prefavUrl
index = 0

while 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">)
    bacUrl = re.findall(reg, favPage)

    if bacUrl:
        p = re.sub('&', '&', bacUrl[0])
        favUrl = prefavUrl + p
        print favUrl
    else:
        break

你可能感兴趣的:(c++,python)