整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Python網(wǎng)絡(luò)爬蟲-爬取QQ空間相冊(cè)

          析QQ空間

          登錄QQ空間

          爬取第一步,分析站點(diǎn),首先需要知道如何登錄QQ空間。最初想法是用requests庫配置登錄請(qǐng)求,模擬登錄,但是不久便放棄了這一思路,請(qǐng)看下圖↓

          login

          根據(jù)登錄按鈕綁定的監(jiān)聽事件可以追蹤到該按鈕的點(diǎn)擊事件如下:

          login function

          賬號(hào)加密是必然的,但這一堆堆的代碼真心不好解析,有耐心的勇士盡情一試!

          在排除這種登錄方法后,選擇selenium模擬用戶登錄不失為省時(shí)省力的方法,而且我們只是需要通過selenium完成登錄,獲取到Cookies和后面講述的g_tk參數(shù)后,就可以停用了,所以效率并不太低。

          分析空間相冊(cè)

          登錄以后,頁面會(huì)跳轉(zhuǎn)至 [https://user.qzone.qq.com/{QQ_NUMBER}](javascript:;), 這時(shí)把鼠標(biāo)移到導(dǎo)航欄你會(huì)發(fā)現(xiàn),所有的導(dǎo)航欄鏈接都是javascript:; 。沒錯(cuò)就是這么坑,一切都是暗箱操作。

          當(dāng)然這并不難處理,使用調(diào)試工具捕獲點(diǎn)擊后產(chǎn)生的請(qǐng)求,然后過濾出正確的請(qǐng)求包即可。因?yàn)榫W(wǎng)絡(luò)包非常多,那么怎么過濾呢,猜想相冊(cè)數(shù)據(jù)的API必然會(huì)返回個(gè)列表list,嘗試過濾list然后逐個(gè)排除,最后定位到請(qǐng)求包。下面是通過fcg_list過濾后的數(shù)據(jù)包,列表信息以jsonp格式返回,稍作處理即可當(dāng)做json格式來讀取(后面有講)。

          album list

          從Headers和Response可以分別獲取到兩組重要信息:

          1. request 獲取相冊(cè)列表所需的請(qǐng)求信息,包括請(qǐng)求鏈接和參數(shù)
          2. response 數(shù)據(jù)包包含的所有相冊(cè)的信息,是每個(gè)相冊(cè)所含照片對(duì)應(yīng)的請(qǐng)求包參數(shù)的數(shù)據(jù)來源

          先看請(qǐng)求包:

          # url
          https://h5.qzone.qq.com/proxy/domain/photo.qzone.qq.com/fcgi-bin/fcg_list_album_v3
          
          # args
          g_tk: 477819917
          callback: shine0_Callback
          t: 691481346
          hostUin: 123456789
          uin: 123456789
          appid: 4
          inCharset: utf-8
          outCharset: utf-8
          source: qzone
          plat: qzone
          format: jsonp
          notice: 0
          filter: 1
          handset: 4
          pageNumModeSort: 40
          pageNumModeClass: 15
          needUserInfo: 1
          idcNum: 4
          callbackFun: shine0
          _: 1551788226819
          

          其中hostUin, uin都是QQ號(hào),g_tk是必須的且每次重新登錄都會(huì)更新(后面有講如何獲取),其它有些參數(shù)不是必須的,我嘗試后整理出如下請(qǐng)求參數(shù):

          query = {
           'g_tk': self.g_tk,
           'hostUin': self.username,
           'uin': self.username,
           'appid': 4,
           'inCharset': 'utf-8',
           'outCharset': 'utf-8',
           'source': 'qzone',
           'plat': 'qzone',
           'format': 'jsonp'
          }
          

          接下來看jsonp格式的跨域響應(yīng)包:

          shine0_Callback({
           "code":0,
           "subcode":0,
           "message":"",
           "default":0,
           "data":
          {
           "albumListModeSort" : [
           {
           "allowAccess" : 1,
           "anonymity" : 0,
           "bitmap" : "10000000",
           "classid" : 106,
           "comment" : 11,
           "createtime" : 1402661881,
           "desc" : "",
           "handset" : 0,
           "id" : "V13LmPKk0JLNRY",
           "lastuploadtime" : 1402662103,
           "modifytime" : 1408271987,
           "name" : "畢業(yè)季",
           "order" : 0,
           "pre" : "http:\/\/b171.photo.store.qq.com\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfGuwSk58K2rQY!\/a\/dIY29GUbJgAA",
           "priv" : 1,
           "pypriv" : 1,
           "total" : 4,
           "viewtype" : 0
           },
          

          shine0_Callback是請(qǐng)求包的callbackFun參數(shù)決定的,如果沒這個(gè)參數(shù),響應(yīng)包會(huì)以_Callback作為默認(rèn)名,當(dāng)然這都不重要。所有相冊(cè)信息以json格式存入albumListModeSort中,上面僅截取了一個(gè)相冊(cè)的信息。

          相冊(cè)信息中,name代表相冊(cè)名稱,id作為唯一標(biāo)識(shí)可用于請(qǐng)求該相冊(cè)內(nèi)的照片信息,而pre僅僅是一個(gè)預(yù)覽縮略圖的鏈接,無關(guān)緊要。

          分析單個(gè)相冊(cè)

          與獲取相冊(cè)信息類似,進(jìn)入某一相冊(cè),使用cgi_list過濾數(shù)據(jù)包,找到該相冊(cè)的照片信息

          photo list

          同樣的道理,根據(jù)數(shù)據(jù)包可以獲取照片列表信息的請(qǐng)求包和響應(yīng)信息,先看請(qǐng)求:

          # url
          https://h5.qzone.qq.com/proxy/domain/photo.qzone.qq.com/fcgi-bin/cgi_list_photo
          
          # args
          g_tk: 477819917
          callback: shine0_Callback
          t: 952444063
          mode: 0
          idcNum: 4
          hostUin: 123456789
          topicId: V13LmPKk0JLNRY
          noTopic: 0
          uin: 123456789
          pageStart: 0
          pageNum: 30
          skipCmtCount: 0
          singleurl: 1
          batchId: 
          notice: 0
          appid: 4
          inCharset: utf-8
          outCharset: utf-8
          source: qzone
          plat: qzone
          outstyle: json
          format: jsonp
          json_esc: 1
          question: 
          answer: 
          callbackFun: shine0
          _: 1551790719497
          

          其中有幾個(gè)關(guān)鍵參數(shù):

          1. g_tk - 與相冊(cè)列表參數(shù)一致
          2. topicId - 與相冊(cè)列表參數(shù)中的id一致
          3. pageStart - 本次請(qǐng)求照片的起始編號(hào)
          4. pageNum - 本次請(qǐng)求的照片數(shù)量

          為了一次性獲取所有照片,可以將pageStart設(shè)為0,pageNum設(shè)為所有相冊(cè)所含照片的最大值。

          同樣可以對(duì)上面的參數(shù)進(jìn)行簡(jiǎn)化,在相冊(cè)列表請(qǐng)求參數(shù)的基礎(chǔ)上添加topicId,pageStart和pageNum三個(gè)參數(shù)即可。

          下面來看返回的照片列表信息:

          shine0_Callback({
           "code":0,
           "subcode":0,
           "message":"",
           "default":0,
           "data":
          {
           "limit" : 0,
           "photoList" : [
           {
           "batchId" : "1402662093402000",
           "browser" : 0,
           "cameratype" : " ",
           "cp_flag" : false,
           "cp_x" : 455,
           "cp_y" : 388,
           "desc" : "",
           "exif" : {
           "exposureCompensation" : "",
           "exposureMode" : "",
           "exposureProgram" : "",
           "exposureTime" : "",
           "flash" : "",
           "fnumber" : "",
           "focalLength" : "",
           "iso" : "",
           "lensModel" : "",
           "make" : "",
           "meteringMode" : "",
           "model" : "",
           "originalTime" : ""
           },
           "forum" : 0,
           "frameno" : 0,
           "height" : 621,
           "id" : 0,
           "is_video" : false,
           "is_weixin_mode" : 0,
           "ismultiup" : 0,
           "lloc" : "NDN0sggyKs3smlOg6eYghjb0ZRsmAAA!",
           "modifytime" : 1402661792,
           "name" : "QQ圖片20140612104616",
           "origin" : 0,
           "origin_upload" : 0,
           "origin_url" : "",
           "owner" : "123456789",
           "ownername" : "123456789",
           "photocubage" : 91602,
           "phototype" : 1,
           "picmark_flag" : 0,
           "picrefer" : 1,
           "platformId" : 0,
           "platformSubId" : 0,
           "poiName" : "",
           "pre" : "http:\/\/b171.photo.store.qq.com\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfSk58K2rQY!\/a\/dIY29GUbJgAA&bo=pANtAgAAAAABCeY!",
           "raw" : "http:\/\/r.photo.store.qq.com\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfSk58K2rQY!\/r\/dIY29GUbJgAA",
           "raw_upload" : 1,
           "rawshoottime" : 0,
           "shoottime" : 0,
           "shorturl" : "",
           "sloc" : "NDN0sggyKs3smlOg6eYghjb0ZRsmAAA!",
           "tag" : "",
           "uploadtime" : "2014-06-13 20:21:33",
           "url" : "http:\/\/b171.photo.store.qq.com\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfSk58K2rQY!\/b\/dIY29GUbJgAA&bo=pANtAgAAAAABCeY!",
           "width" : 932,
           "yurl" : 0
           },
           // ...
           ]
           "t" : "952444063",
           "topic" : {
           "bitmap" : "10000000",
           "browser" : 0,
           "classid" : 106,
           "comment" : 1,
           "cover_id" : "NDN0sggyKs3smlOg6eYghjb0ZRsmAAA!",
           "createtime" : 1402661881,
           "desc" : "",
           "handset" : 0,
           "id" : "V13LmPKk0JLNRY",
           "is_share_album" : 0,
           "lastuploadtime" : 1402662103,
           "modifytime" : 1408271987,
           "name" : "畢業(yè)季",
           "ownerName" : "707922098",
           "ownerUin" : "707922098",
           "pre" : "http:\/\/b171.photo.store.qq.com\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfGuwSk58K2rQY!\/a\/dIY29GUbJgAA",
           "priv" : 1,
           "pypriv" : 1,
           "share_album_owner" : 0,
           "total" : 4,
           "url" : "http:\/\/b171.photo.store.qq.com\/psb?\/V13LmPKk0JLNRY\/eSAslg*mYWaytEtLysg*Q*5Km91gIWfGuwSk58K2rQY!\/b\/dIY29GUbJgAA",
           "viewtype" : 0
           },
           "totalInAlbum" : 4,
           "totalInPage" : 4
          }
          

          返回的照片信息都存于photoList, 上面同樣只截取了一張照片的信息,后面一部分返回的是當(dāng)前相冊(cè)的一些基本信息。totalInAlbum, totalInPage存儲(chǔ)了當(dāng)前相冊(cè)總共包含的照片數(shù)及本次返回的照片數(shù)。而我們需要下載的圖片鏈接則是url!

          OK, 到此,所有請(qǐng)求和響應(yīng)數(shù)據(jù)都分析清楚了,接下來便是coding的時(shí)候了。

          確定爬取方案

          1. 創(chuàng)建qqzone類,初始化用戶信息
          2. 使用Selenium模擬登錄
          3. 獲取Cookies和g_tk
          4. 使用requests獲取相冊(cè)列表信息
          5. 遍歷相冊(cè),獲取照片列表信息并下載照片

          創(chuàng)建qqzone類

          class qqzone(object):
           """QQ空間相冊(cè)爬蟲"""
           def __init__(self, user):
           self.username = user['username']
           self.password = user['password']
          

          模擬登錄

          from selenium import webdriver
          from selenium.webdriver.common.keys import Keys
          from selenium.common.exceptions import WebDriverExceptio
          
          # ...
          
          def _login_and_get_args(self):
           """登錄QQ,獲取Cookies和g_tk"""
           opt = webdriver.ChromeOptions()
           opt.set_headless()
          
           driver = webdriver.Chrome(chrome_options=opt)
           driver.get('https://i.qq.com/')
           # time.sleep(2)
          
           logging.info('User {} login...'.format(self.username))
           driver.switch_to.frame('login_frame')
           driver.find_element_by_id('switcher_plogin').click()
           driver.find_element_by_id('u').clear()
           driver.find_element_by_id('u').send_keys(self.username)
           driver.find_element_by_id('p').clear()
           driver.find_element_by_id('p').send_keys(self.password)
           driver.find_element_by_id('login_button').click()
          
           time.sleep(1)
           driver.get('https://user.qzone.qq.com/{}'.format(self.username))
          

          此處需要注意的是:

          1. 使用selenium需要安裝對(duì)應(yīng)的webdriver
          2. 可以通過webdriver.Chrome()指定瀏覽器位置,否則默認(rèn)從環(huán)境變量定義的路徑查找
          3. 如果電腦打開瀏覽器較慢,可能需要在driver.get后sleep幾秒

          獲取 Cookies

          使用selenium獲取Cookies非常方便

          self.cookies = driver.get_cookies()
          

          獲取 g_tk

          獲取g_tk最開始可以說是本爬蟲最大的難點(diǎn),因?yàn)閺木W(wǎng)頁中根本找不到直接寫明的數(shù)值,只有各種函數(shù)調(diào)用。為此我全局搜索,發(fā)現(xiàn)好多地方都有其獲取方式。

          g_tk

          最后選擇了其中一處,通過selenium執(zhí)行腳本的功能成功獲取到了g_tk!

          self.g_tk = driver.execute_script('return QZONE.FP.getACSRFToken()')
          

          到此,selenium的使命就完成了,剩下的將通過requests來完成。

          初始化 request.Session

          接下來需要逐步生成請(qǐng)求然后獲取數(shù)據(jù)。但是為方便起見,這里使用會(huì)話的方式請(qǐng)求數(shù)據(jù),配置好cookie和headers,省的每次請(qǐng)求都設(shè)置一遍。

          def _init_session(self):
           self.session = requests.Session()
           for cookie in self.cookies:
           self.session.cookies.set(cookie['name'], cookie['value'])
           self.session.headers = {
           'Referer': 'https://qzs.qq.com/qzone/photo/v7/page/photo.html?init=photo.v7/module/albumList/index&navBar=1',
           'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'
           }
          

          請(qǐng)求相冊(cè)信息

          獲取相冊(cè)信息,需要先封裝好請(qǐng)求參數(shù),然后通過session.get爬取數(shù)據(jù),再通過正則匹配以json格式讀取jsonp數(shù)據(jù),最后解析所需的name和id。

          def _get_ablum_list(self):
           """獲取相冊(cè)的列表信息"""
           album_url = '{}{}'.format(
           'https://h5.qzone.qq.com/proxy/domain/photo.qzone.qq.com/fcgi-bin/fcg_list_album_v3?',
           self._get_query_for_request())
          
           logging.info('Getting ablum list id...')
           resp = self.session.get(album_url)
           data = self._load_callback_data(resp)
          
           album_list = {}
           for item in data['data']['albumListModeSort']:
           album_list[item['name']] = item['id']
          
           return album_list
          

          其中的參數(shù)組合來自下面的函數(shù)_get_query_for_request函數(shù)。

          def _get_query_for_request(self, topicId=None, pageStart=0, pageNum=100):
           """獲取請(qǐng)求相冊(cè)信息或照片信息所需的參數(shù)
          
           Args:
           topicId: 每個(gè)相冊(cè)對(duì)應(yīng)的唯一標(biāo)識(shí)符
           pageStart: 請(qǐng)求某個(gè)相冊(cè)的照片列表信息所需的起始頁碼
           pageNum: 單次請(qǐng)求某個(gè)相冊(cè)的照片數(shù)量
          
           Returns:
           一個(gè)組合好所有請(qǐng)求參數(shù)的字符串
           """
           query = {
           'g_tk': self.g_tk,
           'hostUin': self.username,
           'uin': self.username,
           'appid': 4,
           'inCharset': 'utf-8',
           'outCharset': 'utf-8',
           'source': 'qzone',
           'plat': 'qzone',
           'format': 'jsonp'
           }
           if topicId:
           query['topicId'] = topicId
           query['pageStart'] = pageStart
           query['pageNum'] = pageNum
           return '&'.join('{}={}'.format(key, val) for key, val in query.items())
          

          其中的jsonp解析函數(shù)如下,主體部分就是一個(gè)正則匹配,非常簡(jiǎn)單。

          def _load_callback_data(self, resp):
           """以json格式解析返回的jsonp數(shù)據(jù)"""
           try:
           resp.encoding = 'utf-8'
           data = loads(re.search(r'.*?\(({.*}).*?\).*', resp.text, re.S)[1])
           return data
           except ValueError:
           logging.error('Invalid input')
          

          解析并下載照片

          獲取相冊(cè)列表后,逐個(gè)請(qǐng)求照片列表信息,進(jìn)而逐一下載

          def _get_photo(self, album_name, album_id):
           """獲取單個(gè)相冊(cè)的照片列表信息,并下載該相冊(cè)所有照片"""
           photo_list_url = '{}{}'.format(
           'https://h5.qzone.qq.com/proxy/domain/photo.qzone.qq.com/fcgi-bin/cgi_list_photo?',
           self._get_query_for_request(topicId=album_id))
          
           logging.info('Getting photo list for album {}...'.format(album_name))
           resp = self.session.get(photo_list_url)
           data = self._load_callback_data(resp)
           if data['data']['totalInPage'] == 0:
           return None
          
           file_dir = self.get_path(album_name)
           for item in data['data']['photoList']:
           path = '{}/{}.jpg'.format(file_dir, item['name'])
           logging.info('Downloading {}-{}'.format(album_name, item['name']))
           self._download_image(item['url'], path)
          

          下載圖片也是通過request,記得設(shè)置超時(shí)時(shí)間。

          def _download_image(self, url, path):
           """下載單張照片"""
           try:
           resp = self.session.get(url, timeout=15)
           if resp.status_code == 200:
           open(path, 'wb').write(resp.content)
           except requests.exceptions.Timeout:
           logging.warning('get {} timeout'.format(url))
           except requests.exceptions.ConnectionError as e:
           logging.error(e.__str__)
           finally:
           pass
          

          爬取測(cè)試

          • 爬取過程

          capturing

          • 爬取結(jié)果

          downloaded photos

          寫在最后

          1. 如果將請(qǐng)求參數(shù)中的format由jsonp改成json,則可以直接獲取json數(shù)據(jù)
          2. 本用例并未使用多進(jìn)程或多線程,所以速率不算快,還有待優(yōu)化的地方

          前段時(shí)間小編刷抖音的時(shí)候,刷到了咱們前端小伙伴制作的3D炫酷相冊(cè),居然那么火,細(xì)思一下,隨著3D動(dòng)畫的普及,廣泛的運(yùn)作在各個(gè)平臺(tái),各官網(wǎng)都在實(shí)現(xiàn)3D頁面。它可以更接近于真實(shí)的展示我們的產(chǎn)品和介紹,帶來極強(qiáng)的視覺沖擊感。所以說,為了讓自己更加優(yōu)秀,css3 3D動(dòng)畫必不可少。下面這篇文章,將帶你初步了解CSS3實(shí)現(xiàn)酷炫的3D旋轉(zhuǎn)透視




          要想自己的網(wǎng)頁能有3D特效,必須要會(huì)透視。

          透視 perspective(基礎(chǔ)問題,可以在我的推薦書籍中學(xué)習(xí)到)

          • 在2D平面產(chǎn)生近大遠(yuǎn)小視覺立體,但是只是效果二維的
          • 如果想在網(wǎng)頁產(chǎn)生3D效果需要透視(理解成3D物體投影在2D平面內(nèi))。
          • 模擬人類的視覺位置,可認(rèn)為安排一只眼睛去看
          • 透視我們也稱為視距:視距就是人的眼睛到屏幕的距離
          • 距離視覺點(diǎn)越近的在電腦平面成像越大,越遠(yuǎn)成像越小
          • 透視的單位是像素


          圖片來源網(wǎng)絡(luò)

          正文:

        1. CSS3 3D 轉(zhuǎn)換的常用API介紹
        2. CSS3 3D 應(yīng)用場(chǎng)景
        3. CSS3 3D 實(shí)現(xiàn)一個(gè)立方體
        4. 1.CSS3 3D 轉(zhuǎn)換的常用API介紹

          首先先上一張css 3D的坐標(biāo)系:


          接下來我們來介紹幾個(gè)常用的api:


          旋轉(zhuǎn)

          • rotateX()
          • rotateY()
          • rotateZ() 以上幾個(gè)api分別代表繞x,y,z軸旋轉(zhuǎn),如下例子為繞x軸旋轉(zhuǎn)的例子:



          相關(guān)代碼如下:

          <style>
          .d3-wrap {
           position: relative;
           width: 300px;
           height: 300px;
           margin: 120px auto;
           /* 規(guī)定如何在 3D 空間中呈現(xiàn)被嵌套的元素 */
           transform-style: preserve-3d;
           transform: rotateX(0) rotateY(45deg);
           transform-origin: 150px 150px 150px;
          }
          
          .rotateX {
           width: 200px;
           height: 200px;
           background-color: #06c;
           transition: transform 2s;
           animation: rotateX 6s infinite;
          }
          
          @keyframes rotateX {
           0% {
           transform: rotateX(0);
           }
           100% {
           transform: rotateX(360deg);
           } 
          }
          </style>
          <div class="d3-wrap">
           <div class="rotateX"></div>
          </div>
          復(fù)制代碼

          位移(Transform)

          • translateX(x) 定義 3D 轉(zhuǎn)化,僅使用用于 X 軸的值
          • translateY(y) 定義 3D 轉(zhuǎn)化,僅使用用于 Y 軸的值
          • translateZ(z) 定義 3D 轉(zhuǎn)化,僅使用用于 Z 軸的值 以上幾個(gè)api分別代表相對(duì)x,y,z軸的位移,如下例子為向z軸位移的例子:


          這里我們需要注意的是為了能看出位移的效果,我們需要在父容器上加如下屬性:


          .d3-wrap {
           transform-style: preserve-3d;
           perspective: 500;
           /* 設(shè)置元素被查看位置的視圖 */
           -webkit-perspective: 500;
          }

          當(dāng)為元素定義 perspective 屬性時(shí),其子元素會(huì)獲得透視效果,而不是元素本身。 代碼如下:

          .d3-wrap {
           position: relative;
           width: 300px;
           height: 300px;
           margin: 120px auto;
           transform-style: preserve-3d;
           perspective: 500;
           -webkit-perspective: 500;
           transform: rotateX(0) rotateY(45deg);
           transform-origin: center center;
          }
          
          .transformZ {
           width: 200px;
           height: 200px;
           background-color: #06c;
           transition: transform 2s;
           animation: transformZ 6s infinite;
          }
          
          @keyframes transformZ {
           0% {
           transform: translateZ(100px);
           }
           100% {
           transform: translateZ(0);
           } 
          }

          3D縮放

          • scaleX(x) 給定一個(gè) X 軸的3D 縮放轉(zhuǎn)換值
          • scaleY(x) 給定一個(gè) Y 軸的3D 縮放轉(zhuǎn)換值
          • scaleZ(x) 給定一個(gè) Z 軸的3D 縮放轉(zhuǎn)換值 縮放設(shè)置和上面的類似,這里就不做過多介紹了。

          理論上說以上三種常見變換已經(jīng)夠用了,值得關(guān)注的是我們要想讓元素呈現(xiàn)出3D效果,以下不可忽視的API也很重要:


          2.CSS3 3D 應(yīng)用場(chǎng)景

          css 3D主要應(yīng)用在網(wǎng)站的交互和模型效果上,比如:

          • 3D輪播圖
          • 3D產(chǎn)品介紹
          • 室內(nèi)3D仿真
          • h5 3D活動(dòng)頁面,比較典型的就是某年淘寶的年終總結(jié)H5
          • 3D數(shù)據(jù)可視化成圖
          • 3D模型圖 其實(shí)如果css 3D用的熟悉了,一些基本的3D模型完全可以用css畫出來。

          3.CSS3 3D 實(shí)現(xiàn)一個(gè)立方體


          核心思路就是用6個(gè)面去拼接,通過設(shè)置rotate和translate來調(diào)整相互之間的位置,如下:



          具體代碼如下:

          .container {
           position: relative;
           width: 300px;
           height: 300px;
           margin: 120px auto;
           transform-style: preserve-3d;
           /* 為了讓其更有立體效果 */
           transform: rotateX(-30deg) rotateY(45deg);
           transform-origin: 150px 150px 150px;
           animation: rotate 6s infinite;
          }
          .container .page {
           position: absolute;
           width: 300px;
           height: 300px;
           text-align: center;
           line-height: 300px;
           color: #fff;
           background-size: cover;
          }
          .container .page:first-child {
           background-image: url(./my.jpeg);
           background-color: rgba(0,0,0,.2);
          }
          .container .page:nth-child(2) {
           transform: rotateX(90deg);
           transform-origin: 0 0;
           transition: transform 10s;
           background-color: rgba(179, 15, 64, 0.6);
           background-image: url(./my2.jpeg);
          }
          
          .container .page:nth-child(3) {
           transform: translateZ(300px);
           background-color: rgba(22, 160, 137, 0.7);
           background-image: url(./my3.jpeg);
          }
          
          .container .page:nth-child(4) {
           transform: rotateX(-90deg);
           transform-origin: -300px 300px;
           background-color: rgba(210, 212, 56, 0.2);
           background-image: url(./my4.jpeg);
          }
          .container .page:nth-child(5) {
           transform: rotateY(-90deg);
           transform-origin: 0 0;
           background-color: rgba(201, 23, 23, 0.6);
           background-image: url(./my5.jpeg);
          }
          .container .page:nth-child(6) {
           transform: rotateY(-90deg) translateZ(-300px);
           transform-origin: 0 300px;
           background-color: rgba(16, 149, 182, 0.2);
           background-image: url(./my6.jpeg);
          }

          html結(jié)構(gòu)

          <div class="container">
           <div class="page">A</div>
           <div class="page">B</div>
           <div class="page">C</div>
           <div class="page">D</div>
           <div class="page">E</div>
           <div class="page">F</div>
          </div>

          擴(kuò)展

          我們可以基于上面介紹的,給父元素添加動(dòng)畫或者拖拽效果,這樣就可以做成更有交互性的3D方塊了,比如置骰子游戲vr場(chǎng)景3D相冊(cè)等等,具體實(shí)現(xiàn)我會(huì)抽空依次總結(jié)出來,記得關(guān)注哦~





          作者:徐小夕_Lab實(shí)驗(yàn)室
          鏈接:https://juejin.im/post/5dd16b39f265da0bca78958e



          喜歡小編的可以點(diǎn)個(gè)贊關(guān)注小編哦,小編每天都會(huì)給大家分享文章。

          我自己是一名從事了多年的前端老程序員,小編為大家準(zhǔn)備了新出的前端編程學(xué)習(xí)資料,免費(fèi)分享給大家!

          如果你也想學(xué)習(xí)前端,那么幫忙轉(zhuǎn)發(fā)一下然后再關(guān)注小編后私信【1】可以得到我整理的這些前端資料了(私信方法:點(diǎn)擊我頭像進(jìn)我主頁有個(gè)上面有個(gè)私信按鈕)

          奧PicHome介紹

          這是一款基于 PHP + MySQL 的開源項(xiàng)目,選定本地電腦的圖庫目錄之后,就能變成一個(gè)很漂亮的相冊(cè)網(wǎng)頁,并且可以通過分類、標(biāo)簽、顏色、鏈接、注釋、時(shí)長(zhǎng)、尺寸等參數(shù)檢索內(nèi)容,支持預(yù)覽圖片、視頻、音頻,甚至 txt 文檔 。

          官方提供了一個(gè)演示站點(diǎn):http://pichome.oaooa.com/

          可以輕松地放大縮小、翻轉(zhuǎn)鏡像查看,并且可以查看和下載原圖,全憑之后可以通過左右鍵來瀏覽內(nèi)容,可播放視頻、音頻,最有用的就是搜索功能了,找圖快才用的爽。

          基于 PHP + MySQL 環(huán)境則可以部署在各種設(shè)備中,比如服務(wù)器、NAS、個(gè)人電腦、云服務(wù)器等,部署后可以在任何瀏覽器打開,所以手機(jī)電腦都可以方便的訪問,最重要的是免費(fèi)、開源,還是相當(dāng)不錯(cuò)的。

          安裝

          官方安裝部署文檔: https://www.yuque.com/pichome/install

          本次采用nginx+php7搭建

          Gitee下載 https://gitee.com/zyx0814/Pichome/releases

          下載安裝包:筆者這邊下載Pichome-beta3.3.tar.gz。

          github下載 https://github.com/zyx0814/Pichome/releases

          國內(nèi)使用gitee地址
          https://gitee.com/zyx0814/Pichome/releases
          備用下載: http://js.funet8.com/centos_software/Pichome-beta3.3.tar.gz

          解壓安裝

          cd /data/wwwroot/web
          wget http://js.funet8.com/centos_software/Pichome-beta3.3.tar.gz
          tar -zxvf Pichome-beta3.3.tar.gz
          mv Pichome-beta3.3 p.xgss.net

          配置nginx

          nginx的配置

          server {
                  listen 80;
              server_name p.xgss.net;
              root /data/wwwroot/web/p.xgss.net;
              access_log /data/wwwroot/log/p.xgss.net-access.log main_aliyun;
              error_log /dev/null;
          
              location / {
                      index  index.php index.htm index.html;
                      if (!-e $request_filename){
                                  rewrite ^(.*)$ /index.php?s=$1 last;
                      }
                      
                  }
                  location ~ .*\.(php|php5)?$     {
                      fastcgi_pass 127.0.0.1:7300;
                      fastcgi_index index.php;
                      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                      include fastcgi_params;
                  }
          
                  location ~ .*\.(css|js|jpg|jpeg|gif|png|ico|bmp|gz|xml|zip|rar|swf|txt|xls|xlsx|flv|mid|doc|ppt|pdf|mp3|wma|exe)?$ {
                          expires max;
                          access_log off;
                  }
          }
          

          域名解析到服務(wù)器

          配置站點(diǎn)

          訪問: http://p.xgss.net/

          環(huán)境檢查

          配置數(shù)據(jù)庫

          新建數(shù)據(jù)庫用戶

          分配權(quán)限

          填寫管理員信息

          新建庫

          在線升級(jí)

          參考文檔

          官網(wǎng):https://oaooa.com/pichome.html

          開發(fā)者提供了 Windows、Linux 以及 Docker 安裝方式。

          使用Billfish將圖片導(dǎo)入站點(diǎn)

          使用Eagle或者Billfish,在本地windows系統(tǒng)下安裝Billfish素材管理工具,billfish為免費(fèi)的。

          在billfish軟件中將照片分類

          將目錄上傳到服務(wù)器中,庫設(shè)置中添加目錄,就可以在web頁面中顯示你的圖片了。


          主站蜘蛛池模板: 无码一区二区三区老色鬼| 精品视频一区二区三区四区| 亚洲综合一区二区精品久久| 欧洲精品一区二区三区| 国产在线一区二区三区| 日韩精品一区二区三区老鸦窝| 亚洲一区二区三区AV无码| 视频一区二区在线播放| 精品国产一区在线观看| 国产日本一区二区三区| 亚洲一区二区三区在线观看蜜桃 | 免费无码AV一区二区| 一区一区三区产品乱码| 色偷偷久久一区二区三区| 国产午夜精品免费一区二区三区| 一区二区三区观看| 精品一区二区三区在线观看l | 国产乱码精品一区二区三区四川| 精品一区二区三区无码免费视频| 中文字幕Av一区乱码| 国产在线一区二区在线视频| 精品久久国产一区二区三区香蕉 | 国产手机精品一区二区| 日韩精品一区二区三区老鸭窝| 无码国产精品一区二区免费模式| 亚洲一区中文字幕久久| 久久久国产精品亚洲一区| 亚洲国产精品自在线一区二区| 亚洲国产一区二区三区青草影视| 无码人妻精品一区二区三18禁| 99久久精品国产一区二区成人 | 99精品国产一区二区三区2021| 国产高清一区二区三区| 亚洲熟妇AV一区二区三区浪潮| 精品一区二区ww| 无码日韩人妻AV一区免费l| 区三区激情福利综合中文字幕在线一区亚洲视频1| 国产精品视频无圣光一区| 日韩A无码AV一区二区三区| 中文字幕国产一区| 精品一区二区三区东京热|