菜鸟一只蒟蒻一枚轻喷勿嘲
并没有bg,强行搞一个
乱搞哪来正题一说?
电脑室是7-24开着的,想着用来扒一些东西
然后在我逛p站的时候突然想起来自己三位数的收藏图片是不是可以抓下来呢?
写了两个无作业的晚上,
p站的频繁异常登录是会反馈给邮箱的,小心邮箱被刷成999+
这是浏览器F12登录时可以看到的,为了不使跳转后清空我们需要勾上Preserve Log
可以看到这里除了登陆的帐号密码还有一个类似验证的东西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">
就是这张
于是正则匹配一下就搞出来了,需要注意的是这样的一条漫画是没有的
对于一张图片有两种方式保存
urllib.urlretrieve(url, path, rollFunc)#url是图片地址,path是本地目录,那个rollFunc是yy出来的表示下载进度的东西
也就是之前爬百度贴吧用到过的
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)
头一次写着么长的东西,写写停停用了几个晚上。还是很有成就感的(即使代码很丑)
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