Python爬虫之Pixiv
2016-04-28 11:06
573 查看
正在学习Python,想想需要实践检验理论,于是想到爬点东西。作为宇宙纯种动漫宅,对于插画的热爱无人可挡,于是就把目标锁定在了大名鼎鼎的p站,主站地址:http://www.pixiv.net/
目标:得到进入日榜的插画,自动保存图片及相关信息。
PS:该帖用来记录基本流程,以及在实践过程中遇到的一些问题和解决思路;爬取得到的图片自己欣赏即可,请不要随意上传,更不要用于商业用途,尊重画师的劳动成果!
——————————————————————————————————————————
设计一个Pixiv类
一、初始化
二、模拟登陆
三、排行榜信息获取
四、每幅图片所在页面的地址获取
五、图片地址获取
六、创建保存目录
七、保存图片
八、保存图片相关信息
——————————————————————————————————————————
下一篇(续)会贴上完整代码(还有好多地方可以改进!!)
目标:得到进入日榜的插画,自动保存图片及相关信息。
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动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- 爬虫笔记
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- Python去掉字符串中空格的方法