整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          使用 Python 獲取 QQ 群投票數據

          使用 Python 獲取 QQ 群投票數據

          者:solideogloria

          來源:https://blog.yasking.org/a/python-and-selenium-qqvote.html

          抽時間研究下QQ群投票信息的獲取,比較適合(高頻次/投票人數較多)的投票統計。不知道QQ群有沒有API可以獲取投票信息,反正找了一圈沒發現。那就想想看怎么辦

          QQ客戶端肯定是沒辦法了...自然而然的想到網頁版也有群空間之類的地方,可以下載群文件,查看群相冊什么的。去碰碰運氣,然而只可以發起投票,不能獲取投票的人名稱什么的。比較難辦,最后翻翻用手機看看,天無絕人之路,在投票頁面可以復制投票地址。

          類似這樣的URL: http://client.qun.qq.com/qqweb/m/qun/vote/detail.html?_lv=38105&_wv=1031&_bid=2035&src=3&groupuin=151496851&fid=93a8070900000000d38621575e800***

          在瀏覽器中直接打開會出現"載入中,請稍后..."的字眼。這是因為沒有登陸,沒有權限

          在這里登陸自己的QQ,再訪問就可以了

          此時的選項是不可點擊的,因為網頁檢測你的瀏覽環境不是手機界面,并且是不可觸摸的

          在Chrome下很好解決,只需進入響應式模式即可,如果是火狐,則需要進入火狐后再次點擊"加載觸摸事件",就可以點擊進入詳情頁

          既然在瀏覽器端已經可以獲取到這些數據,那么應該就可以使用python和selenium來獲取數據

          自然而然的想到如何讓Chrome和Firefox來進入這種模式呢?

          單單換UA和窗口尺寸是不行的,因為不會加載觸摸事件。

          Firefox driver我沒有找到這樣的操作,好在Chrome可以。主要代碼如下:

          1. #!/bin/env python

          2. # -*- coding:utf-8 -*-

          3. from selenium import webdriver

          4. from selenium.webdriver.chrome.options import Options

          5. presets=[

          6. {"key":"1080 x 1920","name":"Nexus 5 Portrait","width":1080,"height":1920},

          7. ]

          8. mobile_emulation={

          9. "deviceMetrics": { "width": 360, "height": 640, "pixelRatio": 3.0 },

          10. "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36" }

          11. chrome_options=Options

          12. chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)

          13. driver=webdriver.Chrome(chrome_options=chrome_options)

          這樣獲得的driver就可以正常瀏覽投票頁面了

          還有個值得注意的是當投票人數比較多的情況下,不會一次加載完成的。每當鼠標滾動到最下方,就會加載一些數據。我最開始本打算用selenium進行點擊拖動來加載數據,后來查詢到可以用js控制右側的滾動條來實現

          這里比較偷懶,嘗試拖動三次,其實應該在首頁獲取投票人數,第一次加載100人,看看QQ的js,找到之后一次加載多少數據后,得到循環的次數...

          1. # 滑動界面獲取全部投票

          2. try:

          3. for _ in range(3):

          4. js="var q=document.body.scrollTop=10000"

          5. driver.execute_script(js)

          6. time.sleep(2)

          7. except:

          8. pass

          其它的就沒什么好說的了,先登錄,然后訪問投票頁面。

          完整的代碼在這里:python-qqvote

          只獲取了投票第一項的數據,如果不知道投票選項,需要在投票首頁的地方獲取投票選項數量,比較懶...就這樣吧

          QQ投票頁面的數據中只有用戶昵稱,比較可惜,不過可以在QQ群空間獲取QQ號和昵稱的對應關系。

          獲取QQ群成員的代碼在這里:python-qun-people

          參考:

          • https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation

          • http://blog.csdn.net/winterto1990/article/details/48215941

          題圖:pexels,CC0 授權。

          閩南網]

          - 英雄聯盟幸運召喚師現在已經開放,活動是上周五才剛開的,因為這次也是突然就開了,官方也沒有宣傳,所以應該很多小伙伴還不知道,以下是活動地址,最新一期的,可以進入頁面登錄賬號看看是不是本期幸運星。

          - 【幸運召喚師】

          - 1、活動地址:http://lol.qq.com/act/a20180224lucky/index.html

          - 2、活動時間:10月26日~11月6日(預計)

          - 3、關于幸運星獲得說明

          - 如果進入后提示說自己不是本期幸運星,大家不要放棄,有小號的登錄看看,一般等級低的比等級高的容易獲得資格,此外,這個資格是官方隨機給的,所以也是只能憑運氣。

          - 4、關于活動獎勵說明

          - 這個活動就是抽皮膚折扣的,一次抽三種,但只能在頁面購買皮膚時才有優惠,如果是抽到折扣后,再到商城去買是不會打折的,而且必須先擁有英雄才能買皮膚。

          - 以上就是幸運召喚師本次活動說明,想了解更多游戲資訊嗎?請繼續關注琵琶網吧,這里有最新最全的游戲資訊和游戲攻略等你來看。

          信大家都是知道游戲的吧。

          這玩意還是很有意思的,無論是超級瑪麗,還是魂斗羅,亦或者是王者榮耀以及陰陽師。

          當然,這篇文章不涉及到那么牛逼的游戲,這里就簡單的做一個小游戲吧。

          先給它取個名字,就叫“球球作戰”吧。

          咳咳,簡單易懂嘛

          玩法

          任何人進入游戲輸入名字然后就可以連接進入游戲,控制一個小球。

          你可以操作這個小球進行一些動作,比如:移動,發射子彈。

          通過殺死其他玩家來獲取積分,并在排行榜上進行排名。

          其實這類游戲有一個統一的名稱,叫做IO類游戲,在這個網站中有大量的這類游戲:https://iogames.space/

          這個游戲的github地址:https://github.com/lionet1224/node-game

          在線體驗: http://120.77.44.111:3000/

          演示GIF:

          準備工作

          首先制作這個游戲,我們需要的技術為:

          • 前端
            • Socket.io
            • Webpack
          • 后端
            • Node
            • Socket.io
            • express
            • ...

          并且你需要對以下技術有一定了解:

          • Canvas
          • 面向對象
          • ES6
          • Node
          • Promise

          其實本來想使用denots來開發的,但是因為我對這兩項技術都是半生不熟的階段,所以就不拿出來獻丑了。

          游戲架構

          后端服務需要做的是:

          • 存儲生成的游戲對象,并且將其發送給前端。
          • 接收前端的玩家操作,給游戲對象進行數據處理

          前端需要做的是:

          • 接收后端發送的數據并將其渲染出來。
          • 將玩家的操作發送給服務器

          這也是典型的狀態同步方式開發游戲。

          后端服務搭建開發

          因為前端是通過后端的數據驅動的,所以我們就先開發后端。

          搭建起一個Express服務

          首先我們需要下載express,在根目錄下輸入以下命令:

          // 創建一個package.json文件
          > npm init
          // 安裝并且將其置入package.json文件中的依賴中
          > npm install express socket.io --save
          // 安裝并置入package.json的開發依賴中
          > npm install cross-env nodemon --save-dev
          
          

          這里我們也可以使用cnpm進行安裝

          然后在根目錄中瘋狂建文件夾以及文件。

          image.png

          我們就可以得出以上的文件啦。

          解釋一下分別是什么東西:

          • public 存儲一些資源
          • src 開發代碼
            • core 核心代碼
            • objects 玩家、道具等對象
            • client 前端代碼
            • servers 后端代碼
            • shared 前后端共用常量

          編寫基本代碼

          然后我們在server.js中編寫啟動服務的相關代碼。

          // server.js
          // 引入各種模塊
          const express = require('express')
          const socketio = require('socket.io');
          const app = express();
          
          const Socket = require('./core/socket');
          const Game = require('./core/game');
          
          // 啟動服務
          const port = process.env.PORT || 3000;
          const server = app.listen(3000, () => {
            console.log('Server Listening on port: ' + port)
          })
          
          // 實例游戲類
          const game = new Game;
          
          // 監聽socket服務
          const io = socketio(server)
          // 將游戲以及io傳入創建的socket類來統一管理
          const socket = new Socket(game, io);
          
          // 監聽連接進入游戲的回調
          io.on('connect', item => {
            socket.listen(item)
          })
          
          

          上面的代碼還引入了兩個其他文件core/game、core/socket

          這兩個文件中的代碼,我大致的編寫了一下。

          // core/game.js
          class Game{
            constructor(){
              // 保存玩家的socket信息
              this.sockets = {}
              // 保存玩家的游戲對象信息
              this.players = {};
              // 子彈
              this.bullets = [];
              // 最后一次執行時間
              this.lastUpdateTime = Date.now();
              // 是否發送給前端數據,這里將每兩幀發送一次數據
              this.shouldSendUpdate = false;
              // 游戲更新
              setInterval(this.update.bind(this), 1000 / 60);
            }
          
            update(){
          
            }
          
            // 玩家加入游戲
            joinGame(){
          
            }
          
            // 玩家斷開游戲
            disconnect(){
          
            }
          }
          
          module.exports = Game;
          
          
          // core/socket.js
          const Constants = require('../../shared/constants')
          
          class Socket{
            constructor(game, io){
              this.game = game;
              this.io = io;
            }
          
            listen(){
              // 玩家成功連接socket服務
              console.log(`Player connected! Socket Id: ${socket.id}`)
            }
          }
          
          module.exports = Socket
          
          

          core/socket中引入了常量文件,我們來看看我在其中是怎么定義的。

          // shared/constants.js
          module.exports = Object.freeze({
            // 玩家的數據
            PLAYER: {
              // 最大生命
              MAX_HP: 100,
              // 速度
              SPEED: 500,
              // 大小
              RADUIS: 50,
              // 開火頻率, 0.1秒一發
              FIRE: .1
            },
          
            // 子彈
            BULLET: {
              // 子彈速度
              SPEED: 1500,
              // 子彈大小
              RADUIS: 20
            },
          
            // 道具
            PROP: {
              // 生成時間
              CREATE_TIME: 10,
              // 大小
              RADUIS: 30
            },
          
            // 地圖大小
            MAP_SIZE: 5000,
          
            // socket發送消息的函數名
            MSG_TYPES: {
              JOIN_GAME: 1,
              UPDATE: 2,
              INPUT: 3
            }
          })
          
          

          Object.freeze() 方法可以凍結一個對象。一個被凍結的對象再也不能被修改;凍結了一個對象則不能向這個對象添加新的屬性,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結一個對象后該對象的原型也不能被修改。freeze() 返回和傳入的參數相同的對象。- MDN

          通過上面的四個文件的代碼,我們已經擁有了一個具備基本功能的后端服務結構了。

          接下來就來將它啟動起來吧。

          創建啟動命令

          package.json中編寫啟動命令。

          // package.json
          {
              // ...
              "scripts": {
                "dev": "cross-env NODE_ENV=development nodemon src/servers/server.js",
                "start": "cross-env NODE_ENV=production nodemon src/servers/server.js"
              }
              //..
          }
          
          

          這里的兩個命令devstart都使用到了cross-envnodemon,這里解釋一下:

          • cross-env 設置環境變量,這里可以看到這個后面還有一個NODE_ENV=development/production,判斷是否是開發模式。
          • nodemon 這個的話說白了就是監聽文件變化并重置Node服務。

          啟動服務看一下吧

          執行以下命令開啟開發模式。

          > npm run dev
          
          

          可以看到我們成功的啟動服務了,監聽到了3000端口。

          在服務中,我們搭載了socket服務,那要怎么測試是否有效呢?

          所以我們現在簡單的搭建一下前端吧。

          Webpack搭建前端文件

          我們在開發前端的時候,用到模塊化的話會開發更加絲滑一些,并且還有生產環境的打包壓縮,這些都可以使用到Webpack。

          我們的打包有兩種不同的環境,一種是生產環境,一種是開發環境,所以我們需要兩個webpack的配置文件。

          當然傻傻的直接寫兩個就有點憨憨了,我們將其中重復的內容給解構出來。

          我們在根目錄下創建webpack.common.jswebpack.dev.js、webpack.prod.js三個文件。

          此步驟的懶人安裝模塊命令:

          npm install @babel/core @babel/preset-env babel-loader css-loader html-webpack-plugin mini-css-extract-plugin optimize-css-assets-webpack-plugin terser-webpack-plugin webpack webpack-dev-middleware webpack-merge webpack-cli \--save-dev

          // webpack.common.js
          const path = require('path');
          const MiniCssExtractPlugin = require('mini-css-extract-plugin');
          const HtmlWebpackPlugin = require('html-webpack-plugin');
          
          module.exports = {
            entry: {
              game: './src/client/index.js',
            },
            // 將打包文件輸出到dist文件夾
            output: {
              filename: '[name].[contenthash].js',
              path: path.resolve(__dirname, 'dist'),
            },
            module: {
              rules: [
                // 使用babel解析js
                {
                  test: /\.js$/,
                  exclude: /node_modules/,
                  use: {
                    loader: "babel-loader",
                    options: {
                      presets: ['@babel/preset-env'],
                    },
                  },
                },
                // 將js中的css抽出來
                {
                  test: /\.css$/,
                  use: [
                    {
                      loader: MiniCssExtractPlugin.loader,
                    },
                    'css-loader',
                  ],
                },
              ],
            },
            plugins: [
              new MiniCssExtractPlugin({
                filename: '[name].[contenthash].css',
              }),
              // 將處理后的js以及css置入html中
              new HtmlWebpackPlugin({
                filename: 'index.html',
                template: 'src/client/html/index.html',
              }),
            ],
          };
          
          

          上面的代碼已經可以處理css以及js文件了,接下來我們將它分配給developmentproduction中,其中production將會壓縮jscss以及html。

          // webpack.dev.js
          const { merge } = require('webpack-merge')
          const common = require('./webpack.common')
          
          module.exports = merge(common, {
            mode: 'development'
          })
          
          
          // webpack.prod.js
          const { merge } = require('webpack-merge')
          const common = require('./webpack.common')
          // 壓縮js的插件
          const TerserJSPlugin = require('terser-webpack-plugin')
          // 壓縮css的插件
          const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
          
          module.exports = merge(common, {
            mode: 'production',
            optimization: {
              minimizer: [new TerserJSPlugin({}), new OptimizeCssAssetsPlugin({})]
            }
          })
          
          

          上面已經定義好了三個不同的webpack文件,那么該怎么樣使用它們呢?

          首先開發模式,我們需要做到修改了代碼就自動打包代碼,那么代碼如下:

          // src/servers/server.js
          const webpack = require('webpack')
          const webpackDevMiddleware = require('webpack-dev-middleware')
          
          const webpackConfig = require('../../webpack.dev')
          // 前端靜態文件
          const app = express();
          app.use(express.static('public'))
          
          if(process.env.NODE_ENV === 'development'){
            // 這里是開發模式
            // 這里使用了webpack-dev-middleware的中間件,作用就是代碼改動就使用webpack.dev的配置進行打包文件
            const compiler = webpack(webpackConfig);
            app.use(webpackDevMiddleware(compiler));
          } else {
            // 上線環境就只需要展示打包后的文件夾
            app.use(express.static('dist'))
          }
          
          

          接下來就在package.json中添加相對應的命令吧。

          {
          //...
            "scripts": {
              "build": "webpack --config webpack.prod.js",
              "start": "npm run build && cross-env NODE_ENV=production nodemon src/servers/server.js"
            },
          //...
          }
          
          

          接下來,我們試試devstart的效果吧。

          可以看到使用npm run dev命令后不僅啟動了服務還打包了前端文件。

          再試試npm run start

          也可以看到先打包好了文件再啟動了服務。

          我們來看看打包后的文件。

          測試Socket是否有效

          先讓我裝一下前端的socket.io。

          > npm install socket.io-client --save
          
          

          然后編寫一下前端文件的入口文件:

          // src/client/index.js
          import { connect } from './networking'
          
          Promise.all([
            connect()
          ]).then(() => {
          
          }).catch(console.error)
          
          

          可以看到上面代碼我引入了另一個文件networking,我們來看一下:

          // src/client/networking
          import io from 'socket.io-client'
          
          // 這里判斷是否是https,如果是https就需要使用wss協議
          const socketProtocal = (window.location.protocol.includes('https') ? 'wss' : 'ws');
          // 這里就進行連接并且不重新連接,這樣可以制作一個斷開連接的功能
          const socket = io(`${socketProtocal}://${window.location.host}`, { reconnection: false })
          
          const connectPromise = new Promise(resolve => {
            socket.on('connect', () => {
              console.log('Connected to server!');
              resolve();
            })
          })
          
          export const connect = onGameOver => {
            connectPromise.then(()=> {
              socket.on('disconnect', () => {
                console.log('Disconnected from server.');
              })
            })
          }
          
          

          上面的代碼就是連接socket,將會自動獲取地址然后進行連接,通過Promise傳給index.js,這樣入口文件就可以知道什么時候連接成功了。

          我們現在就去前端頁面中看一下吧。

          可以很清楚的看到,前后端都有連接成功的相關提示。

          創建游戲對象

          我們現在來定義一下游戲中的游戲對象吧。

          首先游戲中將會有四種不同的游戲對象:

          • Player 玩家人物
          • Prop 道具
          • Bullet 子彈

          我們來一一將其實現吧。

          首先他們都屬于物體,所以我給他們都定義一個父類Item:

          // src/servers/objects/item.js
          class Item{
            constructor(data = {}){
              // id
              this.id = data.id;
              // 位置
              this.x = data.x;
              this.y = data.y;
              // 大小
              this.w = data.w;
              this.h = data.h;
            }
          
            // 這里是物體每幀的運行狀態
            update(dt){
            
            }
          
            // 格式化數據以方便發送數據給前端
            serializeForUpdate(){
              return {
                id: this.id,
                x: this.x,
                y: this.y,
                w: this.w,
                h: this.h
              }
            }
          }
          
          module.exports = Item;
          
          

          上面這個類是所有游戲對象都要繼承的類,它定義了游戲世界里每一個元素的基本屬性。

          接下來就是player、Prop、Bullet的定義了。

          // src/servers/objects/player.js
          const Item = require('./item')
          const Constants = require('../../shared/constants')
          
          /**
           * 玩家對象類
           */
          class Player extends Item{
            constructor(data){
              super(data);
          
              this.username = data.username;
              this.hp = Constants.PLAYER.MAX_HP;
              this.speed = Constants.PLAYER.SPEED;
              // 擊敗分值
              this.score = 0;
              // 擁有的buffs
              this.buffs = [];
            }
          
            update(dt){
          
            }
          
            serializeForUpdate(){
              return {
                ...(super.serializeForUpdate()),
                username: this.username,
                hp: this.hp,
                buffs: this.buffs.map(item => item.type)
              }
            }
          }
          
          module.exports = Player;
          
          

          然后是道具以及子彈的定義。

          // src/servers/objects/prop.js
          const Item = require('./item')
          
          /**
           * 道具類
           */
          class Prop extends Item{
            constructor(){
              super();
            }
          }
          
          module.exports = Prop;
          
          
          // src/servers/objects/bullet.js
          const Item = require('./item')
          
          /**
           * 子彈類
           */
          class Bullet extends Item{
            constructor(){
              super();
            }
          }
          
          module.exports = Bullet
          
          

          上面都是簡單的定義,隨著開發會逐漸添加內容。

          添加事件發送

          上面的代碼雖然已經定義好了,但是還需要使用它,所以在這里我們來開發使用它們的方法。

          在玩家輸入名稱加入游戲后,需要生成一個Player的游戲對象。

          // src/servers/core/socket.js
          class Socket{
            // ...
            listen(socket){
              console.log(`Player connected! Socket Id: ${socket.id}`);
          
              // 加入游戲
              socket.on(Constants.MSG_TYPES.JOIN_GAME, this.game.joinGame.bind(this.game, socket));
              // 斷開游戲
              socket.on('disconnect', this.game.disconnect.bind(this.game, socket));
            }
            // ...
          }
          
          

          然后在game.js中添加相關邏輯。

          // src/servers/core/game.js
          const Player = require('../objects/player')
          const Constants = require('../../shared/constants')
          
          class Game{
            // ...
          
            update(){
              const now = Date.now();
              // 現在的時間減去上次執行完畢的時間得到中間間隔的時間
              const dt = (now - this.lastUpdateTime) / 1000;
              this.lastUpdateTime = now;
          
              // 更新玩家人物
              Object.keys(this.players).map(playerID => {
                const player = this.players[playerID];
                player.update(dt);
              })
          
              if(this.shouldSendUpdate){
                // 發送數據
                Object.keys(this.sockets).map(playerID => {
                  const socket = this.sockets[playerID];
                  const player = this.players[playerID];
                  socket.emit(
                      Constants.MSG_TYPES.UPDATE,
                      // 處理游戲中的對象數據發送給前端
                      this.createUpdate(player)
                  )
                })
          
                this.shouldSendUpdate = false;
              } else {
                this.shouldSendUpdate = true;
              }
            }
          
            createUpdate(player){
              // 其他玩家
              const otherPlayer = Object.values(this.players).filter(
                  p => p !== player
              );
          
              return {
                t: Date.now(),
                // 自己
                me: player.serializeForUpdate(),
                others: otherPlayer,
                // 子彈
                bullets: this.bullets.map(bullet => bullet.serializeForUpdate())
              }
            }
          
            // 玩家加入游戲
            joinGame(socket, username){
              this.sockets[socket.id] = socket;
          
              // 玩家位置隨機生成
              const x = (Math.random() * .5 + .25) * Constants.MAP_SIZE;
              const y = (Math.random() * .5 + .25) * Constants.MAP_SIZE;
              this.players[socket.id] = new Player({
                id: socket.id,
                username,
                x, y,
                w: Constants.PLAYER.WIDTH,
                h: Constants.PLAYER.HEIGHT
              })
            }
          
            disconnect(socket){
              delete this.sockets[socket.id];
              delete this.players[socket.id];
            }
          }
          
          module.exports = Game;
          
          

          這里我們開發了玩家的加入以及退出,還有Player對象的數據更新,以及游戲的數據發送。

          現在后端服務已經有能力提供內容給前端了,接下來我們開始開發前端的界面吧。

          前端界面開發

          上面的內容讓我們開發了一個擁有基本功能的后端服務。

          接下來來開發前端的相關功能吧。

          接收后端發送的數據

          我們來看看后端發過來的數據是什么樣的吧。

          先在前端編寫接收的方法。

          // src/client/networking.js
          import { processGameUpdate } from "./state";
          
          export const connect = onGameOver => {
            connectPromise.then(()=> {
              // 游戲更新
              socket.on(Constants.MSG_TYPES.UPDATE, processGameUpdate);
          
              socket.on('disconnect', () => {
                console.log('Disconnected from server.');
              })
            })
          }
          
          export const play = username => {
            socket.emit(Constants.MSG_TYPES.JOIN_GAME, username);
          }
          
          
          // src/client/state.js
          export function processGameUpdate(update){
              console.log(update);
          }
          
          
          // src/client/index.js
          import { connect, play } from './networking'
          
          Promise.all([
            connect()
          ]).then(() => {
            play('test');
          }).catch(console.error)
          
          

          上面的代碼就可以讓我們進入頁面就直接加入游戲了,去頁面看看效果吧。

          image.png

          原文鏈接: https://mp.weixin.qq.com/s/hoc5YXVRDDV_7jGmrO5Vfg


          主站蜘蛛池模板: 色婷婷香蕉在线一区二区| 日本免费一区二区三区四区五六区 | 精品视频一区二区观看| 亚洲AV日韩精品一区二区三区| 国产一区二区三区91| 亚洲国产精品成人一区| 国产一区在线视频观看| 在线观看视频一区二区| 国产精品亚洲午夜一区二区三区| 国产精品一区二区av| 色狠狠一区二区三区香蕉蜜桃| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 国产精品福利一区二区久久| 国产亚洲一区二区手机在线观看 | 国产乱码精品一区二区三区四川| 亚洲午夜一区二区电影院| 久久久久无码国产精品一区 | 国产免费无码一区二区| 国产在线精品一区免费香蕉| 亚洲Aⅴ无码一区二区二三区软件| 人妻夜夜爽天天爽一区| 国产激情一区二区三区小说| 国产精品视频分类一区| 一区二区三区视频| 亚无码乱人伦一区二区| 天天视频一区二区三区| 日韩在线观看一区二区三区| 日本一区二区三区在线看| 国产一区二区三区电影| 日韩av片无码一区二区三区不卡| 四虎精品亚洲一区二区三区| 亚洲AV永久无码精品一区二区国产 | 久久亚洲中文字幕精品一区四| 国产福利一区二区在线视频| 日本精品夜色视频一区二区 | 一区二区三区日韩| 久久青青草原一区二区| 日本在线观看一区二区三区| 手机看片福利一区二区三区| 色欲综合一区二区三区| 国产一区二区成人|