欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【Python爬虫案例学习】下载某图片网站的所有图集

程序员文章站 2022-06-16 21:29:56
前言 其实很简短就是利用爬虫的第三方库Requests与BeautifulSoup。 其实就几行代码,但希望没有开发基础的人也能一下子看明白,所以大神请绕行。 基本环境配置 python 版本:2.7 IDE :pycharm 相关模块 完整代码 ......

前言

其实很简短就是利用爬虫的第三方库requests与beautifulsoup。
其实就几行代码,但希望没有开发基础的人也能一下子看明白,所以大神请绕行。

基本环境配置

  • python 版本:2.7
  • ide :pycharm

    相关模块

import urllib2
import io
import random
import urllib
from bs4 import beautifulsoup
import re
import os

完整代码

import urllib2
import io
import random
import urllib
from bs4 import beautifulsoup
import re
import os

import sys
reload(sys)
sys.setdefaultencoding('utf8')
'''
遇到不懂的问题?python学习交流群:821460695满足你的需求,资料都已经上传群文件,可以自行下载!
'''
def gethtml(url):
    #尽可能让爬虫显示为一个正常用户。若不设置,则发送的请求中,user-agent显示为python+版本
    user_agent = [
        'mozilla/5.0 (windows nt 5.2) applewebkit/534.30 (khtml, like gecko) chrome/12.0.742.122 safari/534.30',
        'mozilla/5.0 (windows nt 5.1; rv:5.0) gecko/20100101 firefox/5.0',
        'mozilla/4.0 (compatible; msie 8.0; windows nt 5.2; trident/4.0; .net clr 1.1.4322; .net clr 2.0.50727; .net4.0e; .net clr 3.0.4506.2152; .net clr 3.5.30729; .net4.0c)',
        'opera/9.80 (windows nt 5.1; u; zh-cn) presto/2.9.168 version/11.50',
        'mozilla/5.0 (windows; u; windows nt 5.1; zh-cn) applewebkit/533.21.1 (khtml, like gecko) version/5.0.5 safari/533.21.1',
        'mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0; .net clr 2.0.50727; .net clr 3.0.04506.648; .net clr 3.5.21022; .net4.0e; .net clr 3.0.4506.2152; .net clr 3.5.30729; .net4.0c)'        
    ]
    #设置网页编码格式,解码获取到的中文字符
    encoding = "gb18030"
    #构造http请求头,设置user-agent
    header = {"user-agent":random.choice(user_agent)}
    #构造发送请求
    request = urllib2.request(url,headers=header)
    #发送请求,获取服务器响应回来的html页面
    html = urllib2.urlopen(request).read()
    #使用beautifulsoup处理的html页面,类似dom
    soup = beautifulsoup(html,from_encoding=encoding)
    return soup

# 获取整个站点所有图集的页码
def getpagenum(url):
    soup = gethtml(url)
    # 直接在站点首页获取所有图集的总页码
    nums=soup.find_all('a',class_='page-numbers')
    # 除掉“下一页”的链接,并获取到最后一页
    totlepage = int(nums[-2].text)
    return totlepage

#获取指定页面下图集名称和链接
def getpicnameandlink(url):
    
    soup = gethtml(url)
    meun = []
    #类似html dom对象,直接查找id为“pins”的ul标签,返回的结果是一个dom对象
    targetul = soup.find("ul",id="pins")
    if targetul:    
        #获取该ul下所有的超链接,返回值的类型是list,find_all中第二个参数表示某个指定标签的属性
        pic_list = targetul.find_all("a",target="_blank")
        if pic_list:
           # 遍历所有指定的标签a
            for pic in pic_list:
                #获取图集的链接
                link = pic["href"]
                picturename = ""
                #找到标签a中,“class”为“lazy”的img标签。
                #find中,第二个参数表示某个指定标签的属性。
                #在python中class是保留字,所有标签的class属性的名称为“class_”
                img = pic.find("img",class_='lazy')
                if img:
                    # 保证中文字符能够正常转码。
                    picturename = unicode(str(img["alt"]))
                else:
                    continue
                #插入图集名称和对应的url
                meun.append([picturename,link])    
        
        return meun
    return none

#function获取所有的图集名称
def getallaltls(url):
    totalpage = getpagenum(url)
    #获取首页中所有的图集名称。首页的url和其他页面不同,没有page
    meun = getpicnameandlink(url)
    #循环遍历所有的图集页面,获取图集名称和链接
    for pos in range(2,totalpage):
        currenturl = url + "/page/" + str(pos)
        #getpicnameandlink()返回的值是一个list。
        #当一个list插入到另一个list中时,使用extend。
        #若是插入一个值时,可以用append
        meun.extend(getpicnameandlink(currenturl))
    
    return meun
    
# 获取从首页到指定页面所有的图集名称和链接
def getparaltls(url,page):
    meun = getpicnameandlink(url)
        
    for pos in range(2,page):
        currenturl = url + "/page/" + str(pos)
        meun.extend(getpicnameandlink(currenturl))
        
    return meun

#获取单个相册内图片页码
def getsinglepicnum(url):
    soup = gethtml(url)
    #pagenavi还是一个对象(tag),可以通过find_all找出指定标签出来
    pagenavi = soup.find("div",class_="pagenavi")
    pagelink = pagenavi.find_all("a")
    
    num = int(pagelink[-2].text)
    return num


#下载单个相册中的所有图片
def getsinglepic(url,path):
    totalpagenum = getsinglepicnum(url)
    #从第一页开始,下载单个图集中所有的图片
    #range()第二个参数是范围值的上限,循环时不包括该值
    #需要加1以保证读取到所有页面。
    for i in range(1,totalpagenum + 1):
        currenturl = url + "/" + str(i)
        downloadpic(currenturl,path)
       
#下载单个页面中的图片 
def downloadpic(url,path):
    soup = gethtml(url)
    #找出指定图片所在父容器div
    pageimg = soup.find("div",class_="main-image")
    
    if pageimg:
        #找出该div容器中的img,该容器中只有一个img
        img = pageimg.find("img")
        #获取图片的url
        imgurl = img["src"]
        #获取图片的文件名
        restring = r'[a-za-z0-9]+\.jpg'
        reimgname = re.findall(restring,imgurl)
        
        #将图片保存在指定目录下
        path = str(path)
        if path.strip() == "":
            downloadpath = reimgname[0]
        else:
            downloadpath = path + "/" + reimgname[0]
        #伪装一下下载的http请求,否则有些站点不响应下载请求。
        #不设置的话,下载请求中的user-agent为python+版本号
        urllib.urlopener.version = 'mozilla/5.0 (windows nt 6.1) applewebkit/537.36 (khtml, like gecko) chrome/35.0.1916.153 safari/537.36 se 2.x metasr 1.0'
        #下载图片到指定目录中,保留图片在服务器上的文件名
        urllib.urlretrieve(imgurl,downloadpath)
    
def downimgofsite(url,path = ""):
    
    path = str(path)
    #获取所有图集的名称和链接
    meun_list = getallaltls(url)
    directorypath = ""
    
    for meun in meun_list:
        directoryname = meun[0]
        if path.strip() != "":
            directorypath = path + "/" + directoryname
        else:
            directorypath = os.getcwd + "/" + directoryname
        
        if not os.path.exists(directorypath):
            os.makedirs(directorypath)
        
        getsinglepic(meun[1], directorypath)
        

if __name__ == "__main__":
   
    
   # page = 8
    url = "xxxxx"
    menu = getallaltls(url)
    #menu = getparaltls(url, page)  
    
    f = open("tsts.txt","a")
    for i in menu:
        f.write(str(unicode(i[0]))+"\t"+str(i[1])+"\n")
    f.close()