您的位置:首页 > 编程语言 > Python开发

Python爬虫之Pixiv

2016-04-28 11:06 573 查看
   正在学习Python,想想需要实践检验理论,于是想到爬点东西。作为宇宙纯种动漫宅,对于插画的热爱无人可挡,于是就把目标锁定在了大名鼎鼎的p站,主站地址:http://www.pixiv.net/

    目标:得到进入日榜的插画,自动保存图片及相关信息。

    PS:该帖用来记录基本流程,以及在实践过程中遇到的一些问题和解决思路;爬取得到的图片自己欣赏即可,请不要随意上传,更不要用于商业用途,尊重画师的劳动成果!

——————————————————————————————————————————

设计一个Pixiv类

class Pixiv:


一、初始化

def __init__(self):
# 请求报文需要的一些信息
# 登陆地址
self.loginURL = 'https://www.pixiv.net/login.php'
# 头部信息
self.loginHeader = {
'Host': "www.pixiv.net",
'User-Agent': "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/" +
"537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36",
'Referer': "http://www.pixiv.net/",
'Content-Type': "application/x-www-form-urlencoded",
'Connection': "keep-alive"
}
# 包括用户名、密码等表单信息
self.postData = urllib.urlencode({
'mode': 'login',
'return_to': '/',
'pixiv_id': '1983475717@qq.com',
'pass': '********',
'skip': '1'})
# cookie信息,服务器用来识别用户身份
# 获取本地cookie信息,构建一个包含cookie信息的opener
self.cookie = cookielib.LWPCookieJar()
self.cookieHandler = urllib2.HTTPCookieProcessor(self.cookie)
self.opener = urllib2.build_opener(self.cookieHandler)


二、模拟登陆

def get_first_page(self):
# 向服务器发起请求,请求报文内容包括:URL,头部,表单;请求方式为post
request = urllib2.Request(self.loginURL, self.postData, self.loginHeader)
# 用我们新建的包含cookie信息的opener打开,并返回服务器响应报文
response = self.opener.open(request)
# 内容读取,并以UTF-8解码
content = response.read().decode('utf-8')
print u'响应代码:%s' % response.getcode()
return content


三、排行榜信息获取

def get_rank_list(self):
# 进入dailyRank界面
rank_url = 'http://www.pixiv.net/ranking.php?mode=daily&content=illust'
request = urllib2.Request(rank_url)
response = self.opener.open(request)
content = response.read().decode('UTF-8')
print response.getcode()
# 利用正则表达式,找到dailyRank界面内的作品信息(可以保存为.txt说明用)
pattern = re.compile('<section.*?data-rank-text="(.*?)" data-title="(.*?)" ' +
'data-user-name="(.*?)" data-date="(.*?)".*?data-id="(.*?)"', re.S)
# findall返回一个包含5元组的列表
items = re.findall(pattern, content)
# 可以打印出来看看
# for item in items:
#      print item[0], item[1], item[2], item[3], item[4]
print u"已经获得排名、名称、作者、时间、ID信息O(∩_∩)O哈!"
return items


四、每幅图片所在页面的地址获取

def get_img_page(self):
# 每幅图片所在页面地址 = 基地址 + 图片id(这是作者的图片展示地址)
base_url = 'http://www.pixiv.net/member_illust.php?mode=medium&illust_id='
# 从rank界面获取到的id信息派上用场了
illust_id = [item[4] for item in self.get_rank_list()]
# 用一个列表存储所有的页面地址
img_pages = [base_url + str(i) for i in illust_id]
return img_pages


五、图片地址获取

def get_img_urls(self, img_pages):
# 存储所有图片url的列表
img_urls = []
# 遍历所有illust_id界面,前100名
for index, url in enumerate(img_pages[:100]):
print u"正在进入第%d名插画界面" % (index + 1)
request = urllib2.Request(url)
response = self.opener.open(request)
content = response.read().decode('UTF-8')
# 查找原画地址,不同浏览器获得的HTML有差异,以CHROME为准
# 插画的话,直接获得原图;如果是漫画,则获取缩略图
try:
pattern = re.compile('<img alt.*?data-src="(.*?)"', re.S)
img = re.search(pattern, content)
print img.group(1)
except AttributeError:
pattern = re.compile('<div class="multiple.*?src="(.*?)"', re.S)
img = re.search(pattern, content)
print img.group(1)
img_urls.append(img.group(1))
return img_urls

六、创建保存目录

def make_dir(self):
# 获取格式化时间,提取年月日作为目录名称
y_m_d = time.localtime()
path = 'D:/%s_%s_%s' % (str(y_m_d[0]), str(y_m_d[1]), str(y_m_d[2]))
is_exist = os.path.exists(path)
if not is_exist:
os.makedirs(path)
print u"创建目录成功!"
return path
else:
print u"目录已经存在!"
return path

七、保存图片

def save_img_data(self, urls, pages, path):
for i, img_url in enumerate(urls):
filename = path + '/' + str(i) + '.jpg'
# 里面的Referer很重要哦,不然服务器会拒绝访问,也就获取不到原图数据
# 之前没有管Referer,直接抛给我403
# 服务器会检查Referer,来判断是否对这个请求做响应;我们要尽可能模仿正常上网行为。
# 这里的Referer就是我们之前获取到的页面地址
img_headers = {
'Referer': pages[i],
'User-Agent': "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/" +
"537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36"}
img_request = urllib2.Request(img_url, headers=img_headers)
img_response = self.opener.open(img_request)
print img_response.getcode()
data = img_response.read()
# input = raw_input()
# 保存图片到指定目录
if img_response.getcode() == 200:
with open(filename, 'wb') as f:
f.write(data)
print u"保存第%d张图片中" % i


八、保存图片相关信息

def save_info(self, items, path):
# 记录前100名的信息
filename = path + '/info.txt'
infos = u'前100名信息:\n'
for item in items[:100]:
infos += u'-----------第%s------------\n' % item[0]
infos += u'Name:%s\nAuthor:%s\nID:%s\n' % (item[1], item[2], item[4])
with open(filename, 'w') as f:
f.write(infos.encode('UTF-8'))


——————————————————————————————————————————

下一篇(续)会贴上完整代码(还有好多地方可以改进!!)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  爬虫 python