整合營銷服務商

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

          免費咨詢熱線:

          python抓取.NET GridView分頁數據實

          python抓取.NET GridView分頁數據實戰

          期,應客戶要求,采集一個舊后臺管理系統中的數據列表,并將數據詳情保存為HTML文件,舊平臺架構為.NET 4.0+easyui,數據列為GridView,這個任務的難點是GridView分頁數據抓取的問題,因為切換分頁的時候,瀏覽器的URL是無變化的,包括HTTP請求頭部、請求參數、請求URL全是一樣,采用常規的方式抓取肯定是行不通的(只能采集到第一頁的數據),下面看看我是如何獲取分頁數據。

          廢話不多說,直接上代碼:

          我是基于BeautifulSoup+requests+python3.7實現數據的抓取;

          首先設置頭部信息,用于保證會話和授權:

          headers={

          'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/8.0; .NET4.0C; .NET4.0E)',

          'Accept': 'text/html, application/xhtml+xml, image/jxr, */*',

          'Content-Type': 'application/x-www-form-urlencoded',

          'Accept-Language': 'zh-CN',

          'Host': '瀏覽器F12,根據實際情況填寫',

          'Cache-Control': 'no-cache',

          'Referer': '瀏覽器F12,根據實際情況填寫',

          'Cookie': 'ASP.NET_SessionId=瀏覽器F12,根據實際情況填寫'

          }

          封裝網絡請求:

          def postRequest(url, encoding='utf8', pageno=1):

          data={

          '__EVENTTARGET': 'DataPager1',

          '__EVENTARGUMENT': f'{pageno}',

          '__LASTFOCUS': '',

          'GridView1_gesoft_hidScrollOffset': '0,0',

          '__VIEWSTATEENCRYPTED': '',

          '__VIEWSTATE':'這個必須要填寫,否則實現不了分頁查詢數據',

          '__EVENTVALIDATION': '可選,盡量填上',

          'HidAddInspectID': '',

          'SCAccept$ValueField': '48:105,110,99,108,117,100,101::97,110,100:115,116,114,105,110,103',

          'DataPager1_input': f'{pageno}',

          'DataPager1$pageSizeList': '10',

          'DdlAuthorYear': 'ALL'

          }


          retryFlag=True

          while retryFlag:

          retryFlag=False

          try:

          response=requests.post(url=url, data=data, headers=headers, timeout=10)

          response.encoding=encoding

          return response

          except Exception as e:

          print(f'postRequest error({url}) ', e)

          retryFlag=True

          time.sleep(5)

          上述代碼中“__VIEWSTATE”參數配置是核心中的核心,這個數據怎么獲取呢,我是通過Wireshark抓包工具獲取,如下圖所示:

          請求參數如圖所示

          為了提高數據采集的穩定性,網絡請求增加了超時重試機制。另外特別提醒,請求一定要設置超時時間,否則會導致任務阻塞。

          好了,核心部分已經講完,至于采集到的數據如何用BeautifulSoup進行處理,大家自行在網上查找相關資料,比較簡單就不再贅述了。

          擊“了解更多”獲取DevExpress v20.2完整版下載

          一般情況下,我們都傾向于使用一個組織比較好的獨立界面來錄入或者展示相關的數據,這樣處理比較規范,也方便顯示比較復雜的數據。不過在一些情況下,我們也可能需要直接在GridView表格上直接錄入或者修改數據,這種對于字段比較少,而且內容相對比較簡單的情況下,效率是比較高的一種輸入方式。本篇隨筆主要介紹在DevExpress程序中使用GridView直接錄入數據并保存的實現,以及使用Winform分頁控件來進行數據直接錄入的實現操作。

          一、在GridView上展示數據

          在GridView上展示數據,只需要綁定數據源給對應的GridControl控件即可,比較簡單,可以綁定的數據格式也是很多,可以是DataTable,也可以支持IEnumerable格式的IList<T>集合對象等等,在我的框架中,傾向于使用IList<T>這種實體類集合的方式。

          在網上大多數例子,綁定的數據源多數采用的是基于DataTable的方式,這種方式顯示的數據受制于不同數據庫的特點,字段可能大小寫不一樣,而且DevExpress操作行列的字段是大小寫敏感的,因此如果你要字段名獲取值的時候,傳入的字段名一定是要大小寫一致,因此在數據庫不同的時候,如Oracle查詢到的字段全部是大寫的,SQLServer則是混合模式的(可以是Pascal,也可以是大寫、小寫)。

          采用實體類集合對于框架層次的操作有很多好處,可以強類型,而且不受具體數據庫的影響,所有交互均通過實體類或者其集合進行處理,相對來說有很大的優勢。

          一般情況下,對實體類的數據源,我們可以通過下面的方式進行數據綁定(使用分頁控件的數據綁定方式)。

          List<DictDataInfo> list=BLLFactory<DictData>.Instance.FindWithPager(condition, this.winGridViewPager1.PagerInfo);
          this.winGridViewPager1.DataSource=list;

          如果需要在GridView上對記錄進行新增修改的,也就是需要存儲綁定數據的狀態的,那么就不能直接使用List<T>集合,而需要使用其BindingList<T>的集合,同樣BindingList<T>實現了IList<T>接口,我們可以通過構造函數new BindingList<T>(list)方式進行類型轉換,然后重新綁定到數據源即可。

          修改下上面的處理,我們可以得到如下的數據綁定方式:

          /// <summary>
          /// 綁定GridControl控件的數據源
          /// </summary>
          private void BindData()
          {
          //使用BindingList可以進行編輯記錄,否則無法存儲新增記錄內容
          var list=BLLFactory<DictData>.Instance.Find(treeConditionSql);
          this.gridControl1.DataSource=new BindingList<DictDataInfo>(list);
          }

          默認情況下,如果這樣綁定,那么字段列名稱會是實體類的屬性名稱,英文的,顯然這樣不太符合我們的顯示處理,我們需要限定幾個字段,而且需要顯示中文內容,那么我們應該為GridView構建幾個綁定的列字段才可以。

          例如我們可以通過函數進行字段列的構建工作,如下所示。

          其中的CreateColumn是為了簡化處理模式引入的擴展函數,主要就是實現綁定字段的增加的,可以理解為下面代碼的處理:

          這樣我們綁定數據源后,就可以顯示指定的一些字段內容了,而且是中文列名稱,如下效果所示。

          二、在GridView上錄入數據和保存數據

          但是,上面小節只是說明了數據如何綁定顯示的,如果需要在GridView上直接錄入數據,那么還需要做一些特殊的代碼處理的。

          在上面我們介紹使用BindingList<T>的數據源方式,確保可以顯示并錄入實體類集合數據的,如下代碼綁定數據源所示。

          如果我們需要設置GridView能夠直接錄入數據,那么需要設置下面幾個屬性,特別是最后那行。

          grv.OptionsBehavior.ReadOnly=false;
          grv.OptionsBehavior.Editable=true;
          grv.OptionsView.NewItemRowPosition=NewItemRowPosition.Bottom;

          對于一些常規的GridView初始化,我們可以通過一個擴展函數實現它的屬性設置。

          grv.InitGridView(GridType.NewItem, false, EditorShowMode.MouseDownFocused);

          我們錄入新的數據行時候,往往需要設置一些相關的屬性,如果ID什么的,那么需要在InitNewRow事件里面進行處理,如下所示,我們希望在新建記錄的時候,保留記錄這個記錄的父ID(來源自左側樹節點的ID信息)

          其中代碼

          grv.SetRowCellValue(i, "DictType_ID", typeId);//存儲記錄的父ID

          需要我們在這個GridView里面有一個隱藏的字段存在(如本例的DictType_ID字段),否則無法存儲這個記錄內容的。

          如果我們需要在錄入完成某個字段內容后,其他字段也做相應的改變,如觸發關聯變化,那么可以在CellValueChanged事件進行處理,如本例我們希望名稱增加后,值和名稱一致變化,那么代碼如下所示。

          這樣我們在界面編輯的時候,就可以得到下面的效果了。

          完成上面步驟,如果我們需要在錄入數據后校驗錄入的信息,并提交數據庫處理,如果成功則提示,那么就需要在事件ValidateRow里面進行處理了。

          校驗記錄內容,我們可以通過下面的代碼進行處理。

          不過一般情況下,我們可以使用擴展函數來封裝這些校驗的處理,以達到簡化代碼的目的。

          校驗通過后提交數據庫,我們首先需要做的方式是定位記錄集合里面當前的記錄,把它轉換為具體的實體類對象,然后寫入新記錄或者更新處理,如下所示。

          運行程序,并在GridView中錄入記錄后,并逐一回車,跳轉到新一行的時候,觸發數據校驗和保存操作,保存成功后提示用戶,并可以繼續錄入新的記錄,非常方便,這個就是使用GridView直接錄入數據并保存的方便地方。

          結合GridControl的右鍵菜單,我們可以實現數據的刪除、打印、導出等常規的功能整合。

          三、基于Winform分頁控件的數據展示和錄入

          在數據記錄比較少的情況下,直接使用GridView進行展示全部記錄,沒有什么問題。但是在數據記錄比較多的時候,如果用GridView全部展開所有的記錄,會比較影響性能,比較好的方式就是對數據進行適當的分頁。

          在Winform開發中,我們使用封裝好的分頁控件來展示數據,這個分頁的特性已經整合在Winform開發框架、混合式開發框架等框架底層里面了,直接調用相應的框架業務類方法,即可獲取對應業務表的分頁記錄,非常方便。

          前面兩個小節都是基于原生的GridView控件對象進行數據的展示和錄入,分頁控件本身也是封裝GridView控件的,因此也是可以直接利用它來進行數據的錄入處理的。使用分頁控件,可以高效提高數據的查詢速度,另外可以利用代碼生成工具Database2Sharp工具進行快速開發好Winform界面,然后進行一定的修改即可,非常方便。

          我們來看看使用分頁控件做的數據展示和錄入界面效果圖。

          利用分頁控件的方式和前面的直接使用GridView的方式大同小異,只是一些細節處理上進行修改即可。

          分頁控件,在利用代碼生成工具Database2Sharp的Winform界面生成的時候,自動帶有下面的分頁控件初始化代碼,我們屏蔽其中的新增和編輯處理事件,因為我們使用直接錄入的方式,不需要彈出對話框進行處理。

          代碼如下所示。

          由于我們使用分頁控件,其在數據綁定的時候,列是自動創建的,因此我們不需要為GridView指定數據列,我們使用分頁控件后的InitGridView的代碼如下所示。


          /// <summary>
          /// 初始化GridView
          /// </summary>
          private void InitGridView()
          { 
          var grd=this.winGridViewPager1.gridControl1;
          var grv=this.winGridViewPager1.gridView1;
          
          #region GridView控件初始化
          
          grv.InitGridView(GridType.NewItem, false, EditorShowMode.MouseDownFocused, "");
          grv.InitNewRow +=delegate(object sender, InitNewRowEventArgs e)
          {
          //數據記錄初始化的時候,設置ID和父節點的ID
          if (this.tree.FocusedNode !=null)
          {
          var i=e.RowHandle;
          var typeId=this.tree.FocusedNode.GetValue("ID");
          grv.SetRowCellValue(i, "ID", Guid.NewGuid().ToString());
          grv.SetRowCellValue(i, "DictType_ID", typeId);//存儲記錄的父ID
          }
          };
          grv.CellValueChanged +=delegate(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
          {
          //如果字段的值發生改變,觸發其他值改變則在此處理
          if (e.Column.FieldName=="Name")
          {
          string value=string.Concat(grv.GetRowCellValue(e.RowHandle, "Value"));
          if (string.IsNullOrEmpty(value))
          {
          grv.SetRowCellValue(e.RowHandle, "Value", e.Value);
          }
          }
          };
          
          grv.ValidateRow +=delegate(object sender, ValidateRowEventArgs e)
          { 
          var result=grd.ValidateRowNull(e, new string[]
          {
          "Name"
          });
          
          //校驗通過后提交數據庫
          if (result)
          {
          //獲取當前操作的記錄對象
          var info=grv.GetFocusedRow() as DictDataInfo;
          
          //如果記錄對象非空,則可以寫入或者更新
          if (info !=null)
          {
          result=BLLFactory<DictData>.Instance.InsertUpdate(info, info.ID);
          
          //如果不能寫入,提示用戶
          if (!result)
          {
          e.Valid=false;
          e.ErrorText=string.Format("寫入數據出錯");
          }
          else
          {
          base.ShowMessageAutoHide();
          }
          }
          }
          };
          
          #endregion
          }


          綁定數據源的方法BindData和直接生成的代碼沒有太大的差別,只是把GridView設置為可編輯即可,代碼如下所示。

          這樣我們就可以實現基于Winform分頁控件的基礎上進行數據的直接錄入操作了,處理方式就是先利用代碼生成工具Database2Sharp進行Winform界面生成,然后進行微調代碼即可,非常方便就可以實現這種快捷的數據錄入了。

          四、基于主從表數據錄入的處理

          在前面的記錄保存和顯示里面,都是采用一個視圖的方式進行數據的展示和錄入的,如果對于主從表的記錄同時錄入,那么就需要主從表兩個GridView來進行展示和數據錄入的了,對于主從表錄入相對復雜一些,具體如何操作呢?

          這里我們依舊采用分頁控件來進行數據的分頁及直接錄入數據操作,而且增加了主從表數據同時在一個GridControl界面上進行處理。

          這樣主表記錄為字典類型,從表為字典明細項目,得到的數據展示界面效果如下所示。

          當然我們可直接在底部進行數據的錄入,包括主表記錄和從表的明細記錄,都可以一氣呵成的錄入并進行保存處理的,界面效果如下所示。

          GridView的主從關系需要設置好集合的映射關系,我們需要通過設置GridLevelNode集合實現主從表關系的處理的。

          初始化從表的GridView2和主從表關系的代碼如下所示:

          通過上面的初始化代碼,指定了主從表的關系后,我們還需要對綁定的數據源進行一定的處理,才能夠在GridControl控件上顯示主從表關系的記錄。

          首先需要定義一個業務對象,用來存儲主從關系的記錄對象。

          然后在BindData綁定數據的時候,代碼處理如下即可。

          這樣就可以得到開始介紹的主從表界面效果了。

          數據保存的代碼和前面的操作類似,我們需要分別對GridView1和GridView2的數據保存操作進行處理,如下代碼所示。

          GridView2的字典項目明細保存操作如下所示。

          主從表的記錄刪除這里需要順帶介紹一下,由于主從表公用一個右鍵菜單的刪除操作。

          那么處理的時候,我們需要判斷是操作從表還是主表記錄,對它們要分開處理,然后提示是否操作成功,如果成功,我們可以移除這行即可,避免重新更新數據導致的焦點丟失。

          以上就是介紹各種在GridView界面上直接錄入數據并保存的處理操作,雖然一般情況下面,我們建議通過獨立的彈出界面進行內容的展示和錄入,但是對于一些字段較少,或者喜歡直接錄入記錄的用戶來說,這種方式也是一種非常不錯的體驗效果,也可以達到快速錄入的目的,可以把這種方式作為我開發框架數據非常規錄入的補充。

          本文轉載自博客園-伍華聰

          evExpress Winforms Controls 內置140多個UI控件和庫,完美構建流暢、美觀且易于使用的應用程序。DevExpress WinForm v20.1全新發布,想要體驗?點擊文末“了解更多”即可免費下載!!!

          我們知道,基于DevExpress的開發Winform的項目界面的時候,GridControl控件是經常用來綁定數據的,一般以常規的字符內容為主,有時候也會有圖片的顯示需要,那么如果顯示圖片,我們應該如何實現呢?本文將為大家介紹基于原生GridControl控件的圖片綁定顯示操作和基于封裝的分頁控件(封裝GridControl的分頁控件)兩種圖片綁定顯示的操作。

          一、基于原生的GridControl控件圖片綁定

          綁定圖片,一般我們可以在單元格里面綁定byte[]類型或者Image類型,那么控件就會自動顯示圖片出來,當然我們也可以自定義對圖片路徑轉換為圖片然后顯示的,不過就是額外需要增加一些處理而已。

          本例子針對這三種方式分別進行介紹,圖片的綁定操作。

          為了方便演示,我們創建一個菜單對象類,然后構建一些數據用于列表的綁定操作,如下代碼所示。


          /// <summary>
          /// 模擬一個菜單的對象,包括各種類型的圖片信息
          /// </summary>
          public class MenuInfo
          {
          /// <summary>
          /// 編號
          /// </summary>
          public string ID { get; set; }
          
          /// <summary>
          /// 圖標名稱
          /// </summary>
          public string Name { get; set; }
          
          /// <summary>
          /// 圖片路徑
          /// </summary>
          public string ImageFilePath {get;set;}
          
          /// <summary>
          /// 圖標字節
          /// </summary>
          public virtual byte[] EmbedIcon { get; set; }
          
          /// <summary>
          /// 圖標圖片對象
          /// </summary>
          public Image ImageIcon { get; set; }
          
          /// <summary>
          /// 構造函數
          /// 為了展示的方便,在構造函數里面構造相應的數據
          /// </summary>
          public MenuInfo()
          {
          this.ID=Guid.NewGuid().ToString();
          this.Name="測試圖片菜單";
          this.ImageFilePath=Path.Combine(System.Environment.CurrentDirectory, "app.ico");
          if (File.Exists(this.ImageFilePath))
          {
          this.EmbedIcon=FileUtil.FileToBytes(this.ImageFilePath);
          this.ImageIcon=ImageHelper.ImageFromUrl(this.ImageFilePath);
          }
          }
          
          創建GridColumn的時候,我們可以利用GridVIew的擴展函數CreateColumn進行創建幾個不同的列,如下代碼所示。
          
          public partial class FrmRepositoryItemImageEdit : BaseForm
          {
          public FrmRepositoryItemImageEdit()
          {
          InitializeComponent();
          
          CreateGridView();
          }
          
          /// <summary>
          /// 創建gridView1列表所需顯示的列
          /// </summary>
          private void CreateGridView()
          {
          //創建一個隱藏的ID列
          this.gridView1.CreateColumn("ID", "ID").Visible=false;
          //串一個名稱的列,并指定寬度
          this.gridView1.CreateColumn("Name", "名稱", 150);
          
          //創建一個圖片路徑的列,并指定它的編輯控件類型為RepositoryItemImageEdit
          //并為這個列實現ParseEditValue的方法,用于解析路徑為具體的圖片顯示
          this.gridView1.CreateColumn("ImageFilePath", "圖片路徑綁定", 100).CreateImageEdit().ParseEditValue +=(s, e)=>
          {
          if (e.Value !=null && e.Value is string && e.Value.ToString() !=string.Empty)
          {
          e.Value=Image.FromFile(string.Concat(e.Value));
          e.Handled=true;
          }
          };
          
          //創建圖片字節的列,用于顯示圖片
          this.gridView1.CreateColumn("EmbedIcon", "圖片字節綁定", 100);
          //創建圖片對象的列,用于顯示圖片
          this.gridView1.CreateColumn("ImageIcon", "圖片對象綁定", 100);
          }


          上面代碼是創建GridView所需要顯示的列信息,那么我們準備好數據源綁定到列表控件上就可以了,如下代碼所示。


          /// <summary>
          /// 綁定列表數據
          /// </summary>
          private void BindData()
          {
          //構造只有一個記錄的集合
          List<MenuInfo> menuList=new List<MenuInfo>()
          {
          new MenuInfo()
          };
          
          //綁定數據源到列表控件上
          this.gridControl1.DataSource=menuList;
          }


          二、基于分頁控件的圖片綁定

          很多時候,我們需要對數據庫的數據進行分頁顯示,以提高顯示的速度和效率,那么利用分頁控件就可以獲得很多這樣統一的界面和高效率顯示數據的好處,基于分頁控件的處理本質上和上面的過程差不多,不過處理的代碼需要變化一下,從而可以正常的實現圖片綁定顯示操作。


          /// <summary>
          /// 基于分頁控件的圖片顯示案例
          /// </summary>
          public partial class FrmRepositoryItemImageEdit2 : BaseForm
          {
          public FrmRepositoryItemImageEdit2()
          {
          InitializeComponent();
          
          CreateGridView();
          }
          
          /// <summary>
          /// 創建gridView1列表所需顯示的列
          /// </summary>
          private void CreateGridView()
          {
          this.winGridViewPager1.OnPageChanged +=new EventHandler(winGridViewPager1_OnPageChanged);
          this.winGridViewPager1.OnRefresh +=new EventHandler(winGridViewPager1_OnRefresh);
          this.winGridViewPager1.AppendedMenu=this.contextMenuStrip1;
          this.winGridViewPager1.ShowLineNumber=true;
          this.winGridViewPager1.BestFitColumnWith=false;//是否設置為自動調整寬度,false為不設置
          this.winGridViewPager1.gridView1.DataSourceChanged +=new EventHandler(gridView1_DataSourceChanged);
          }
          
          /// <summary>
          /// 綁定數據后,分配各列的寬度
          /// </summary>
          private void gridView1_DataSourceChanged(object sender, EventArgs e)
          {
          //對圖片路徑的列,重新使用RepositoryItemPictureEdit類型
          //然后對該列的控件的ParseEditValue和FormatEditValue函數進行實現,從而實現路徑到圖片的顯示
          var edit=this.winGridViewPager1.gridView1.Columns.ColumnByFieldName("ImageFilePath").CreatePictureEdit(); 
          edit.ParseEditValue +=(s, se)=>
          {
          if (se.Value !=null && se.Value.GetType()==typeof(string) && se.Value.ToString() !=string.Empty)
          {
          if (File.Exists(string.Concat(se.Value)))
          {
          var picture=ImageHelper.ImageFromUrl(string.Concat(se.Value));
          se.Value=picture;
          se.Handled=true;
          
          }
          }
          };
          edit.FormatEditValue +=(s, se)=>
          {
          if (File.Exists(string.Concat(se.Value)))
          {
          var picture=ImageHelper.ImageFromUrl(string.Concat(se.Value));
          se.Value=picture;
          se.Handled=true;
          }
          };
          
          if (this.winGridViewPager1.gridView1.Columns.Count > 0 && this.winGridViewPager1.gridView1.RowCount > 0)
          {
          //統一設置100寬度
          foreach (DevExpress.XtraGrid.Columns.GridColumn column in this.winGridViewPager1.gridView1.Columns)
          {
          column.Width=120;
          }
          
          //可特殊設置特別的寬度
          GridView gridView=this.winGridViewPager1.gridView1;
          if (gridView !=null)
          {
          //gridView.SetGridColumWidth("Note", 200);
          }
          }
          }


          而在分頁控件的數據綁定的時候,我們指定列名的中文名即可,如下代碼所示


          /// <summary>
          /// 綁定列表數據
          /// </summary>
          private void BindData()
          {
          #region 添加別名解析
          
          this.winGridViewPager1.DisplayColumns="Name,ImageFilePath,EmbedIcon,ImageIcon";
          this.winGridViewPager1.AddColumnAlias("ID", "編號");
          this.winGridViewPager1.AddColumnAlias("Name", "名稱");
          this.winGridViewPager1.AddColumnAlias("ImageFilePath", "圖片路徑綁定");
          this.winGridViewPager1.AddColumnAlias("EmbedIcon", "圖片字節綁定");
          this.winGridViewPager1.AddColumnAlias("ImageIcon", "圖片對象綁定");
          
          this.winGridViewPager1.gridView1.OptionsBehavior.Editable=true;
          this.winGridViewPager1.gridView1.OptionsBehavior.ReadOnly=false;
          
          #endregion
          
          //構造只有一個記錄的集合
          List<MenuInfo> menuList=new List<MenuInfo>()
          {
          new MenuInfo()
          };
          
          this.winGridViewPager1.DataSource=menuList;
          }


          以上就是基于GridControl控件上綁定圖片的幾種操作方式,方便我們在項目中參考使用。

          本文轉載自博客園-伍華聰

          點擊下方“了解更多”獲取更多界面開發相關資訊!


          主站蜘蛛池模板: 无码人妻精品一区二区三区66 | 中文字幕Av一区乱码| 大屁股熟女一区二区三区| 91精品国产一区二区三区左线| 国产成人综合亚洲一区| 一本久久精品一区二区| 91精品国产一区| 无码人妻精品一区二区三区99仓本 | 亚拍精品一区二区三区| 国产av天堂一区二区三区| 乱人伦一区二区三区| 美女视频免费看一区二区 | 立川理惠在线播放一区| 国产第一区二区三区在线观看 | 亚洲电影一区二区| 国产一区二区三区久久精品| 人妻少妇AV无码一区二区| 国产乱码精品一区二区三| 精品日本一区二区三区在线观看| 国产一区二区精品久久岳√| 日本一区免费电影| 日韩少妇无码一区二区三区| 视频精品一区二区三区| 亚洲一区二区视频在线观看| 精品国产毛片一区二区无码| 国产在线aaa片一区二区99| 国产日韩一区二区三免费高清| 亚洲无人区一区二区三区| 熟女精品视频一区二区三区| 熟女精品视频一区二区三区| 中文字幕日韩一区二区不卡| 亚洲av成人一区二区三区观看在线 | 亚洲乱码国产一区三区| 久久精品国产一区二区三区肥胖| 熟妇人妻AV无码一区二区三区| 色噜噜狠狠一区二区| 在线精品自拍亚洲第一区| 亚洲乱码国产一区网址| 亚洲午夜精品一区二区| 无码夜色一区二区三区| 国产激情无码一区二区三区|