分析ajax爬取搜狗美女图片

版权声明:原创不易,如若转载,请注明出处! https://blog.csdn.net/MG1723054/article/details/81735834

     前面两篇博客我们分别利用requests请求库抓取页面(链接https://blog.csdn.net/MG1723054/article/details/81604116)和利用selenium模拟浏览器来获取页面数据(链接https://blog.csdn.net/MG1723054/article/details/81630769),这些获取信息的方法也有弊端,对于requests请求库在抓取网页时候,得到的结果可能与浏览器中看到的不一样,这是因为requests获取的是原始的HTML文档,而现实的网页中,浏览器可能经过JavaScript处理后生成的结果,这些数据可能是ajax加jason载的,或者通过JavaScript渲染的;利用selenium抓取数据时候,主要的问题是效率不高。

     下面我们主要来讨论通过分析ajax来获取json数据,获取需要的网址,利用requests模拟ajax请求,最后获得我们想要的数据。

这里,我们用搜狗美女网址为例,如图所示为网页源代码,在源代码中我们没有找到那些图片的url链接。

于是,我们打开开发者模式,如下图所示,点击network按钮,按F5,我们可以看到一系列的请求,我们在XHR中的preview看到一系列的美女图片的ID,以及或图片的url,下拉网页我们看到后面的图片出现时候,XHR请求就增加。然后我们分析不同链接的url的规律,

url=http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jspcategory=%E7%BE%8E%E5%A5%B3&tag=%E5%85%A8%E9%83%A8&start=15&len=15

url=http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jspcategory=%E7%BE%8E%E5%A5%B3&tag=%E5%85%A8%E9%83%A8&start=30&len=15

url=http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jspcategory=%E7%BE%8E%E5%A5%B3&tag=%E5%85%A8%E9%83%A8&start=45&len=15

 

       通过分析上面的链接,我们可以先发现对于不同的链接只是start数据改变,规律是15*n(n=1,2,3,),其他的数据均不改变,通过以上分析,我们给出代码,我们在代码里面详细分析每一个程序的意义

# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a NJUer.
"""
import requests
import time 
from urllib.parse import urlencode  #网址编码
import json  #导入json库
urls=[]
def image_json (url) :###请求库,利用requests请求构造的链接,然后转化为json格式,然后得到图######片的标题和图片链接。
      response=requests.get(url,headers={'User-Agent':'Mozilla/5.0'})
      data=json.loads(response.text)['all_items']
      for m in range(len(data)) :
           items={
                       'image_url':data[m]['thumbUrl'],'title':data[m]['title']
                       }
      
           
           yield items
      
def  image_download(item):###下载图片
      resource=requests.get(item['image_url'])
      item['title']=item['title'].replace('|','_')
      item['title']=item['title'].replace('/','_')###改名,因为有些图片中有些字符不符合jpg
###图片命名规范
      file='C:\\Users\\FangWei\\Desktop\\网络爬虫\\爬取酷狗美女图片\\'+item['title'][0:20]+'.jpg'
      with open (file,'wb') as f:
            f.write(resource.content)###将图片下载,放到指定文件夹
def get_image (offest) :   ###get_image函数主要是构造需要的ajax链接
    base_url='http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jsp?'
    data={'category':'美女',
                  'tag':'全部',
                  'start':str(offest*15),
                  'len':'15',}
    url=base_url+urlencode(data)  ###利用urlencode将字典拼接为一个网址链接
    return url  
def main(offest):
      time.sleep(1) 
      infor=get_image(offest)  #mian函数内部调用get_image函数
    #time.sleep(1)
      for item in  image_json (infor):
           image_download(item)          
if __name__=='__main__' :
      start=time.time()
      for x in range(30):   #设置爬取变量,设置30,根据上面分析表示可以爬取30*15张图片         
          offest=x
          main(offest)           #调用主函数main()
      end=time.time()
      times=end-start
      print(times)
          
            
            
            
          
      

 通过上面的代码,我们就可以完成我们所需要的图片,爬取的部分结果如下:

       最后,我们可以利用进程中的进程池来提高爬取效率,针对该程序,时间缩短了30s左右,因为在里面加了休息一秒,所以结果有差别,如果将time.sleep(1)删除,两个结果运行时间差不多,这是因为爬取是密集型IO操作,利用进程对其效率提高不大,可以考虑线程和协程(python协程还不太成熟),这方面的只是我会在某个时候贴出来。

附:多进程源代码:

# -*- coding: utf-8 -*-
"""
Created on Thu Jul  5 15:43:59 2018

@author: NJUer
"""
# -*- coding: utf-8 -*-
import requests
from multiprocessing.pool  import Pool
import time 
from urllib.parse import urlencode 
import json
urls=[]
def image_json (url) :
      response=requests.get(url,headers={'User-Agent':'Mozilla/5.0'})
      data=json.loads(response.text)['all_items']
      for m in range(len(data)) :
           items={
                       'image_url':data[m]['thumbUrl'],'title':data[m]['title']
                       }
      
           
           yield items
      
def  image_download(item):
      resource=requests.get(item['image_url'])
      item['title']=item['title'].replace('|','_')
      item['title']=item['title'].replace('/','_')
      file='C:\\Users\\FangWei\\Desktop\\网络爬虫\\爬取酷狗美女图片\\'+item['title'][0:10]+'.jpg'
      with open (file,'wb') as f:
            f.write(resource.content)
def get_image (offest) :
    base_url='http://pic.sogou.com/pics/channel/getAllRecomPicByTag.jsp?'
    data={'category':'美女',
                  'tag':'全部',
                  'start':str(offest*15),
                  'len':'15',}
    url=base_url+urlencode(data)
    return url  
def main(offest):
      time.sleep(1)      
      infor=get_image(offest)
    
      for item in  image_json (infor):
           image_download(item)          
if __name__=='__main__' :
      start=time.time()
      pool=Pool()
      offest=[x for x in range(30)]
      pool.map(main,(offest))
      pool.close()
      pool.join()
      end=time.time()
      times=end-start
      print(times)
          
            
            
            
          
      

 原创不易,如需转载,请注明出处和作者,谢谢。

猜你喜欢

转载自blog.csdn.net/MG1723054/article/details/81735834