scrapy爬取帅哥图片网站

前言:关于scrapy的介绍网上有很多,在实现这个爬图片过程也遇到很多坑,我用的是python2.7.15,scrapy版本是1.5,遇到问题时可以根据自己的开发环境寻找对应的帮助文档。先说说主要思路:

1.先了解scrapy,这个是介绍的挺好的文章,还有实战观看

2.分析网站结构,确定爬取策略

3.根据爬虫过程中遇到的问题进行解决,如设置代理,user-agent,禁用cookie等等即防反爬策略

本来想对着那个教程做的一个爬取美女图片,但是鉴于女票不给,所以爬一个帅哥图片的网站,首先是新建项目,在命令行新建一个scrapy项目,并且为这个项目新建一个爬虫程序:具体的步骤是——

在命令行中输入 (1)scrapy startproject BoyDemo,进入该项目,输入(2)scrapy scrapy genspider -t  boy nanrentu.cc,此时把项目复制到eclipse的新建的一个pydev project里面,然后配置好运行方式,具体参考环境配置,然后开始写代码了。


这个是我的例子的大体结构,spiders里面就放爬虫程序,cmdline就是用来启动爬虫程序的,items相当于实体类,存放对应的东西,piplines就是处理实体类的,settings是配置文件,middlewears是中间件处理(个人理解是给爬虫制定策略去更好地爬取),其中cmdline是要自己创建的,我们要先做一些配置:

1.用户代理池的设置:

在middlewares.py找到xxxDownloaderMiddleware,这个是下载器中间件里面有一个process_request方法,我们可以对这个方法进行编写:

 def process_request(self, request, spider):

      
        user_agent_pools=[
                   'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3',
        'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3',
        
        ]
        ua=random.choice(user_agent_pools)
        print '当前使用的user-agent是'+ua
        try:
            request.headers.setdefault('User-Agent',ua)
        except Exception,e:
            print e
            pass
        
        return None

2.ip代理池的配置,我一开始不会爬取,然后多次访问被封我ip了,不能访问那个网站了,所以ip代理池就可以减少爬取不了目标网站,可以在middlewares新建一个类,
class MyproxiesSpiderMiddleware(HttpProxyMiddleware):
      

      def __init__(self,ip=''):  
          self.ip=ip  
          self.IPPOOL=[
      {'ipaddr': 'http://116.213.98.6:8080'},
      {'ipaddr': 'https://60.176.227.182:8118'},
      {'ipaddr': 'https://114.239.125.251:61234'},
      {'ipaddr': 'https://220.191.15.49:6666'},
      {'ipaddr': 'https://222.185.160.95:6666'},
      {'ipaddr': 'http://111.155.116.234:8123'},
      {'ipaddr': 'http://122.114.31.177:808'},
      ]     
      def process_request(self, request, spider):  
          thisip=random.choice(self.IPPOOL)  
          print("this is ip:"+thisip["ipaddr"])  
          request.meta['proxy']=thisip["ipaddr"]
         
          return None

要确保你的ip是可用的,可以上一些免费代理网站查,然后上一些可以检测ip的网站看是否可用,因为刚入门,那些自动爬取有效ip代理池放进数据库,再取出来用的操作还不会,然后在middlewares对进行修改后,就要到settings文件去启用这个下载中间件。

DOWNLOADER_MIDDLEWARES = {
    'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware':123,
    'middlewares.MyproxiesSpiderMiddleware':125,
    'middlewares.HandsomeboyDownloaderMiddleware':2
     
           
}

本来是被注释掉的,这时候启用并写上你的中间件执行顺序,,值越小越先执行。

设置好ip和用户代理池以后,爬虫在访问网站时候就会自动带上这些信息去访问

3.不遵循robot.txt设置,禁用cookie:

在setting上配置:

ROBOTSTXT_OBEY = False

COOKIES_ENABLED = False

4.使pineline可用,就是爬虫执行完parse等一系列方法后,会给item赋值,item返回后又会在pineline文件里面得到相应的处理,要使处理生效,就要在setting文件里面配置

ITEM_PIPELINES = {
    'pipelines.HandsomeboyPipeline': 300,

}

这时候setting文件就配置完毕

spider的编写,比较重要的点就是xpath的使用和深度爬取得应用,下面说明:

           
    def parse(self, response):
        urldata = response.xpath("/html/body/div[@id='nav']/div[@class='nav']/ul//li/a/@href").extract()
        print urldata
        boy = urldata[3]
        
        yield Request(boy,callback=self.next,dont_filter=True)

这个方法是爬虫的一开始的方法,就是获取首页的某个页面的地址,然后调用next方法,一步步调用,其余代码:

   def next(self, response):
        
        
        page_last = response.xpath("/html/body/div[@id='parta']/div[@id='partac']/div[@class='pagelist']/a[last()]/@href").extract_first()
        if page_last != None:                       
            i = page_last.find("_")
            i2 = page_last.find(".")
            str1 = page_last[i+3:i2]
            page_num = str1.encode('utf-8')
            page_a = int(page_num)
            for n in range(1,page_a+1):
                    time.sleep(1)
                    page_url = 'http://www.nanrentu.cc/rh/'+'list_4_'+str(n)+'.html' 
                    
                    request = scrapy.Request(page_url,callback=self.next2,dont_filter=True)                                                                                     
                    yield request
    def next2(self, response):
        page_title_list = response.xpath("/html/body/div[@id='parta']/div[@id='partac']/div[@class='partacpic']/ul[@class='P2']//li/a/@title").extract()        
        page_url_list = response.xpath("/html/body/div[@id='parta']/div[@id='partac']/div[@class='partacpic']/ul[@class='P2']//li/a/@href").extract()
        boy_page_url = page_url_list[0]
        boy_page_url = 'http://www.nanrentu.cc'+boy_page_url
        yield Request(boy_page_url,callback=self.next3,dont_filter=True)  
    def next3(self, response):       
        num = response.xpath("/html/body/div[@id='parta']/div[@class='nc']/div[@class='pagelist']/a/span/b/text()").extract()
        url_pre = response.url
        s = url_pre.split('.')[:-1]
        b = s[0]+'.'
        c = s[1]+'.'
        d = s[2]
        e =b + c +d
        time.sleep(1)
        for x in range(1,int(num[0])+1):
            if x == 1:
                page_url = e+'.html'
            else:
                page_url = e+'_'+str(x)+'.html'    
               
            yield Request(page_url,callback=self.getPic,dont_filter=True)
    def getPic(self,response):
        item = HandsomeboyItem()
        pic_url = response.xpath("/html/body/div[@id='parta']/div[@class='nc']/div[@class='imgbox']/div[@class='piccontext']/div[@class='picshow']/div[@class='picshowtop']/a/img/@src").extract()
        pic_url = 'http://www.nanrentu.cc'+pic_url[0]
        
        item['url'] = pic_url
        return item

最后的getPic就给item赋值并返回item,item就会被相应的管道处理,主要是下载图片,这个类是pinepline文件的一个类

class HandsomeboyPipeline(object):
    def process_item(self, item, spider):
       
        this_url = item['url']
        
        id = re.findall('http://www.nanrentu.cc/uploads/allimg/(.*?).jpg',this_url)
        
        
        a = id[0].find('/')
        id = id[0][a+1:]
        print id
        file = 'D:/temp/' + id + '.jpg'
        print('Downloading :' , file)
        urllib.urlretrieve(this_url, filename=file)
        print('Final Download :' , file)
        return item

其他的要注意的就是包,类的导入正确与否,要结合自己版本来查看。
















猜你喜欢

转载自blog.csdn.net/weixin_37703281/article/details/80543068