Python 爬虫-爬取pixiv特定搜索结果的所有作品-抓取 分析 下载

来源:互联网 发布:惧内之滥觞乎 编辑:程序博客网 时间:2024/05/16 18:29

接上一篇文章 :

Python 爬虫-爬取pixiv特定搜索结果的所有作品-登陆

爬虫的github地址

因为时间的限制,加上回过头看前一篇文章 觉得自己写的着实有点太/详细/;臃肿 )了 因此在之后的文章中将尽可能简洁一些

不知道为什么Pixiv刚刚 又 好像莫名的被墙了 ,我现在只有开vpn才能上了,常态。。。

上一篇文章我们已经成功登陆了

登陆之后 我们就可以搜索特定标签的图片了。如果通过爬虫搜索特定keyword的图片?
以我的小老婆saber举例 ,在Pixiv中搜索saber查看浏览器地址栏变化,发现地址栏为
可以猜测https://www.pixiv.net/search.php?s_mode=s_tag&word=keyword 即 向网页提交特定搜索词keyword的url链接,可以讲上面的saber删除 换另一个搜索词看看,是否是自己想要的搜索页面(经验多了就很明显的看出来,如果有多个信息,就用&分隔)


(第N页的URL  以及搜索模式等 都可以通过地址栏URL找到链接,不再赘述,详细可以看源码)

得到了搜索结果面 我们如何得到所需要的原地地址呢?</strong></p>
直接在搜索结果页面中,右键任意一张图片,点击chrome的检查按钮,就会将这个元素在网页源代码中的位置给出(这里我选择第一张

发现所有图片的元素都非常整齐的放在一个属性中,但却是一个乱码(不知道是P站加密过了还是我这边浏览器的解码问题)
这时候可以换一个方法试试看
随便点开一个图片的链接 记住Pixiv 号,返回搜索页面并查看源代码 ,搜索这个Pixiv号就可以</p>
可以发现图片所指向的链接被包含在 class=image-item标签中 而所有的' image-item' 标签被包含在了div data-reactroot class=' image-items' );
且链接地址就是href的属性; 用BeautifulSoup可以极为方便的解析出这个页面的所有图片的(网络问题 就不给图片了

_itemList=_soup.find_all('li',class_='image-item')
for link in _itemLinks:              url = link.find('a')['href']
面的url就是 所有的我们想要的图片的网页链接(不是图片的链接 ,而是图片详细页的网址,在P站 如果直接get图片地址,会有大概率被判定为盗链,返回403错误

那么如何筛选特点赞数以上的插画呢?

回到搜索页面 对 有赞数的图片 的‘ 赞数’ 右键检查 可以发现 他们都在一个属性值为‘ class="bookmark-count _ui-tooltip" ’ 标签中
因此可以用如下代码获得并筛选搜索页面的图片的赞数

 _links=[]                      _itemList=_soup.find_all('li',class_='image-item')          ###找到image-item标签                             if len(_itemList)<20:                  ###P站有时候网络不稳定 当image-item少于20时 可以判定加载失败 需要重新登陆并搜索              return False                ### 这取决于网络环境                     for item in _itemList:                starList=item.find('a',attrs={'class':"bookmark-count _ui-tooltip"})                        if starList!=None:                           ###没有赞数 的图片 没有 这一属性值,确保starList不为空                    try:                      starNum =int(starList['data-tooltip'].replace('书签','').replace(',',''))      ###把赞数文本替换为数字                  except:                      starNum=0                  if starNum>num:
               ###如果大于筛选条件 则将这张图片加入结果列表  
                    _links.append([item,starNum])                  else:                      continue                else:                  continue          return _links                    </span>###返回 符合要求的 图片 标签和赞数
以上 我们获得了所要的图片的标签 (网址和名字等信息,但网址并不直接可用)
接下来 从标签中获得我们想要的图片url:
def getIdLink(self,_links):          id_link = []          for link in _links:              url = link[0].find('a')['href']      ###从标签中筛选出 pixid号                 id_link.append([url,link[1]])                     return id_link                ###返回pixiv号 和 赞数</pre><br>  
接下来我们通过requests.session.get()访问所得到的图片详情页

for link in _idLink:                                    url=( 'https://www.pixiv.net' +(link[0]))                  starNum=link[1]                                                      page = self._session.get(url)                                 soup = BeautifulSoup(htmlpage.text, 'html.parser')          downInfo=soup.find('div', attrs={'class': 'works_display'})  ###标签中包含图片下载地址 名字 等信息  
之后便是下载这张图片

def downloadPic(self,picInfo,starNum,downPath):                    url_origi = picInfo['src'].replace('c/600x600/img-master', 'img-original')          url_origi = url_origi.replace('_master1200', '')          ###这个标签中的P站图片下载链接 并不是原图而是经过裁剪的 使用字符串的替换可以获得                            </span>### 原图的下载地址 但是原图相较有更大的 403 错误          url_sl = picInfo['src']          print("正在尝试下载:",picInfo['alt'])                      tryTimes=0      ###设置尝试次数,超过三次便放弃这张图片          ifOrigin='_origin_'      ### 检查是否为 原图 的标记          while(1):              try:                  tryTimes+=1                  r = self._session.get(url_origi, headers=self._headers, timeout=3)                  if tryTimes>1:                      print("正在进行第",tryTimes, '次尝试')                      time.sleep(2)                                                         if r.status_code == 404:                      print('无法下载原图')                      r = s.get(url_sl, headers=headers, timeout=3)                      ifOrigin='              ###删除 是否为原图 的标记                    pic = r.content                  if(starNum==0):                      with open(downPath + picInfo['alt'] +ifOrigin+ '.jpg', 'wb') as f:                          f.write(pic)                  if(starNum>0):                      with open(downPath + picInfo['alt'] +'Stars('+ str(starNum)+')'+ifOrigin+'.jpg', 'wb') as f:                          f.write(pic)     ###给文件名标记可以区分是否为原图 ,并 给出赞数                  f.close()                    print("下载成功:", picInfo['alt'],ifOrigin,'Stars(', str(starNum)+')')                  return None              except:                  if tryTimes>=3:                      print('下载失败:', picInfo)                      return None                                                    continue   
到这里 各个主要部分已经讲完了 相较于上一篇登陆 可能的确简略了很多 但这不怪我QAQ P又又又被墙了 ,挂VPN都很难进去,导致我很多地方就没有截图了。
这一篇就先到这里为止。具体还有一些细节(如何保存本地cookies并装载等)没讲,不过这并不影响主要功能 以下再次出我最后重构并加了一些功能的完整代码的github链接GitHub之所以不直接给源码是因为csdn直接贴打段代码会导致卡死 进而倒致排版问题 嗯 亲身经历过
运行截图:



最后秀一波结果




阅读全文
0 0
原创粉丝点击