精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

用Python教你如何“養”一只DHT爬蟲

開發 前端 后端
文講的是要實現一個爬蟲, 所以不會跟協議文檔那么嚴格. 只要保證你能正確請求,回應即可. 用軟件開發的一句話來說: 只要接口一致, 管你內部細節代碼是怎么寫的.

[[108808]]

廢話少說, 直接上菜.

我假設你了解:

1, DHT協議

2, 網絡字節序/主機字節序

3, bencode

4, UDP

5, 種子文件構造

不懂的趕緊去google, 要是缺一個, 我會一口鹽汽水噴死你的!

最重要的是, 你必須會編程!!!!!!! 必須會!!!!!!!!!!!

ok, DHT原理是什么我在這就不寫了, 畢竟會看我這文章的人都是已經知道了的.

本文貼的代碼均為Python, 使用其他編程語言的人可以看注釋. 為了簡單, 只會說大概思路和關鍵性代碼, 細節自行搞定.

本文講的是要實現一個爬蟲, 所以不會跟協議文檔那么嚴格. 只要保證你能正確請求,回應即可. 用軟件開發的一句話來說: 只要接口一致, 管你內部細節代碼是怎么寫的.

第一步, 構建自己的路由表, 這里涉及到大量Python代碼, 請深呼吸:

在構建自己的路由表之前, 得寫兩個輔助函數, 后面會用到:

  1. from hashlib import sha1  
  2. from random import randint  
  3. def node_id():  
  4.     """  
  5.     把爬蟲"偽裝"成正常node, 一個正常的node有ip, port, node ID三個屬性, 因為是基于UDP協議,   
  6.     所以向對方發送信息時, 即使沒"明確"說明自己的ip和port時, 對方自然會知道你的ip和port,   
  7.     反之亦然. 那么我們自身node就只需要生成一個node ID就行, 協議里說到node ID用sha1算法生成,   
  8.     sha1算法生成的值是長度是20 byte, 也就是20 * 8 = 160 bit, 正好如DHT協議里說的那范圍: 0 至 2的160次方,   
  9.     也就是總共能生成1461501637330902918203684832716283019655932542976個獨一無二的node.   
  10.     ok, 由于sha1總是生成20 byte的值, 所以哪怕你寫SHA1(20)或SHA1(19)或SHA1("I am a 2B")都可以,   
  11.     只要保證大大降低與別人重復幾率就行. 注意, node ID非十六進制,   
  12.     也就是說非FF5C85FE1FDB933503999F9EB2EF59E4B0F51ECA這個樣子, 即非hash.hexdigest().  
  13.     """ 
  14.     hash = sha1()  
  15.     s = ""  
  16.     for i in range(20):  
  17.         s += chr(randint(0255))  
  18.     hash.update(s)  
  19.     return hash.digest()  
  20.  
  21. def intify(nid):  
  22.     """這是一個小工具, 把一個node ID轉換為數字. 后面會頻繁用到.""" 
  23.     assert len(nid) == 20 
  24.     return long(nid.encode('hex'), 16#先轉換成16進制, 再變成數字 

協議里說道, table里有bucket, bucket里有node, 每個bucket有K個node, 目前K=8, 即每個bucket有8個node. 由于table范圍是0到2的160次方, 那么一個table最多能有(2的160次方)/K那么多的bucket.

OK, 按照OOP編程思想來說, 那么肯定會有table, bucket, node這3個類, 無OOP的, 自己看著辦.

由于是基于Kademila而寫, 所以我習慣上把這三個類名變為KTable, KBucket, KNode:

  1. class KNode:  
  2.     def __init__(self, nid, ip, port):  
  3.         """  
  4.         nid就是node ID的簡寫, 就不取id這么模糊的變量名了. __init__方法相當于別的OOP語言中的構造方法,   
  5.         在python嚴格來說不是構造方法, 它是初始化, 不過, 功能差不多就行.  
  6.         """ 
  7.         self.nid = nid #node ID  
  8.         self.ip = ip  
  9.         self.port = port  
  10.  
  11.     #以下兩個方法非Python程序員不需關心  
  12.     def __eq__(self, other):  
  13.         return self.nid == other.nid  
  14.     def __ne__(self, other):  
  15.         return self.nid != other.nid  
  16.  
  17.  
  18. class KBucket:  
  19.     def __init__(self, min, max):  
  20.         """  
  21.         min和max就是該bucket負責的范圍, 比如該bucket的min:0, max:16的話,   
  22.         那么存儲的node的intify(nid)值均為: 0到15, 那16就不負責, 這16將會是該bucket后面的bucket的min值.   
  23.         nodes屬性就是個列表, 存儲node. last_accessed代表最后訪問時間, 因為協議里說到,   
  24.         當該bucket負責的node有請求, 回應操作; 刪除node; 添加node; 更新node; 等這些操作時,   
  25.         那么就要更新該bucket, 所以設置個last_accessed屬性, 該屬性標志著這個bucket的"新鮮程度". 用linux話來說, touch一下.  
  26.         這個用來便于后面說的定時刷新路由表.  
  27.         """ 
  28.         self.min = min #最小node ID數字值  
  29.         self.max = max #最大node ID數字值  
  30.         self.nodes = [] #node列表  
  31.         self.last_accessed = time() #最后訪問時間  
  32.  
  33.     def nid_in_range(self, nid):  
  34.         """判斷指定的node ID是否屬于該bucket的范圍里""" 
  35.         return self.min <= intify(nid) < self.max  
  36.  
  37.     def append(self, node):  
  38.         """  
  39.         添加node, 參數node是KNode實例.  
  40.  
  41.         如果新插入的node的nid屬性長度不等于20, 終止.  
  42.         如果滿了, 拋出bucket已滿的錯誤, 終止. 通知上層代碼進行拆表.  
  43.         如果未滿, 先看看新插入的node是否已存在, 如果存在, 就替換掉, 不存在, 就添加,  
  44.         添加/替換時, 更新該bucket的"新鮮程度".  
  45.         """ 
  46.         if len(node.nid) != 20return 
  47.         if len(self.nodes) < 8:  
  48.             if node in self.nodes:  
  49.                 self.nodes.remove(node)  
  50.                 self.nodes.append(node)  
  51.             else:  
  52.                 self.nodes.append(node)  
  53.             self.last_accessed = time()  
  54.         else:  
  55.             raise BucketFull  
  56.  
  57.  
  58. class KTable:  
  59.     """  
  60.     該類只實例化一次.  
  61.     """ 
  62.     def __init__(self, nid):  
  63.         """  
  64.         這里的nid就是通過node_id()函數生成的自身node ID. 協議里說道, 每個路由表至少有一個bucket,   
  65.         還規定第一個bucket的min=0, max=2的160次方, 所以這里就給予了一個buckets屬性來存儲bucket, 這個是列表.  
  66.         """ 
  67.         self.nid = nid #自身node ID  
  68.         self.buckets = [KBucket(02 ** 160)] #存儲bucket的例表  
  69.  
  70.     def append(self, node):  
  71.         """添加node, 參數node是KNode實例""" 
  72.  
  73.         #如果待插入的node的ID與自身一樣, 那么就忽略, 終止接下來的操作.  
  74.         if node.nid == self.nid: return   
  75.  
  76.         #定位出待插入的node應該屬于哪個bucket.  
  77.         index = self.bucket_index(node.nid)  
  78.         bucket = self.buckets[index]  
  79.  
  80.         #協議里說道, 插入新節點時, 如果所歸屬的bucket是滿的, 又都是活躍節點,   
  81.         #那么先看看自身的node ID是否在該bucket的范圍里, 如果不在該范圍里, 那么就把  
  82.         #該node忽略掉, 程序終止; 如果在該范圍里, 就要把該bucket拆分成兩個bucket, 按范圍"公平平分"node.  
  83.         try:  
  84.             bucket.append(node)  
  85.         except BucketFull:  
  86.             if not bucket.nid_in_range(self.nid): return #這個步驟很重要, 不然遞歸循環很狂暴, 導致程序死翹翹.  
  87.             self.split_bucket(index)   
  88.             self.append(node)  
  89.  
  90.     def bucket_index(self, nid):  
  91.         """  
  92.         定位bucket的所在索引  
  93.  
  94.         傳一個node的ID, 從buckets屬性里循環, 定位該nid屬于哪個bucket, 找到后, 返回對應的bucket的索引;   
  95.         沒有找到, 說明就是要創建新的bucket了, 那么索引值就是最大索引值+1.  
  96.         注意: 為了簡單, 就采用循環方式. 這個恐怕不是最有效率的方式.  
  97.         """ 
  98.         for index, bucket in enumerate(self.buckets):  
  99.             if bucket.nid_in_range(nid):  
  100.                 return index  
  101.         return index          
  102.  
  103.     def split_bucket(self, index):  
  104.         """  
  105.         拆表  
  106.  
  107.         index是待拆分的bucket(old bucket)的所在索引值.   
  108.         假設這個old bucket的min:0, max:16. 拆分該old bucket的話, 分界點是8, 然后把old bucket的max改為8, min還是0.   
  109.         創建一個新的bucket, new bucket的min=8, max=16.  
  110.         然后根據的old bucket中的各個node的nid, 看看是屬于哪個bucket的范圍里, 就裝到對應的bucket里.   
  111.         各回各家,各找各媽.  
  112.         new bucket的所在索引值就在old bucket后面, 即index+1, 把新的bucket插入到路由表里.  
  113.         """ 
  114.         old = self.buckets[index]  
  115.         point = old.max - (old.max - old.min)/2 
  116.         new = KBucket(point, old.max)  
  117.         old.max = point  
  118.         self.buckets.insert(index + 1, new)  
  119.         for node in old:  
  120.             if new.nid_in_range(node.nid):  
  121.                 new.append(node)  
  122.         for node in new:  
  123.             old.remove(node)          
  124.  
  125.     def find_close_nodes(self, target):  
  126.         """  
  127.         返回與目標node ID或infohash的最近K個node.  
  128.  
  129.         定位出與目標node ID或infohash所在的bucket, 如果該bucuck有K個節點, 返回.   
  130.         如果不夠到K個節點的話, 把該bucket前面的bucket和該bucket后面的bucket加起來, 只返回前K個節點.  
  131.         還是不到K個話, 再重復這個動作. 要注意不要超出最小和最大索引范圍.  
  132.         總之, 不管你用什么算法, 想盡辦法找出最近的K個節點.  
  133.         """ 
  134.         nodes = []  
  135.         if len(self.buckets) == 0return nodes  
  136.         index = self.bucket_index(target)  
  137.         nodes = self.buckets[index].nodes  
  138.         min = index - 1 
  139.         max = index + 1 
  140.         while len(nodes) < K and (min >= 0 or max < len(self.buckets)):  
  141.             if min >= 0:  
  142.                 nodes.extend(self.buckets[min].nodes)  
  143.             if max < len(self.buckets):  
  144.                 nodes.extend(self.buckets[max].nodes)  
  145.             min -= 1 
  146.             max += 1 
  147.  
  148.         num = intify(target)  
  149.         nodes.sort(lambda a, b, num=num: cmp(num^intify(a.nid), num^intify(b.nid)))  
  150.         return nodes[:K] #K是個常量, K=8 

ok, 路由表這個玩意兒比較有技術含量, 又難以描述, 所以會貼代碼演示. 接下來的DHT客戶端/服務端就不再貼那么多的代碼了, 畢竟處理網絡的代碼太多太復雜, 技術含量不高, 按照DHT協議描述的那樣操作就行了.

 

第二步, 實現DHT客戶端

#p#

實現一個DHT客戶端, 不用都要實現ping, find_node, get_peers, announce_peer操作了, 做一個爬蟲, 僅僅只需要實現find_node功能就能達到目的了. 因為我們只想不停地交朋友而已.

要想加入DHT網絡, 首先得認識第一個已知的node, 這個node最好是長期在線的, 又穩定的. 我這里就認識一個, dht.transmissionbt.com:6881, 由于UDP的原因, 只能接受ip, 所以請提前解析出ip地址.

然后使用DHT協議說的那個find_node操作, 現在解釋一下某些key的潛在意義吧

t: transaction ID的簡稱, 傳輸ID. 起什么作用呢? 由于UDP無3次握手這個機制, 所以任何人都可隨便發送信息給你, 根本就不需與你提前進行連接. 想想這么個情況, 你發送了一請求數據給某node, 然后收到DHT說的回復類型的數據, 即y=r, 但是, 你怎么知道回應的是你之前的哪個請求呢? 所以就要靠t了, 當你發送時, t=aa的話, 對方回應這個請求時, 回應消息的t絕對是aa, 這樣你就能區分了. 在發送之前, 要為該t值注冊一個處理函數, 當收到回應時, 調用該函數進行處理. 記得設置一個定時器, 時間一到, 立馬刪除該函數, 不然你內存飆升. 如果超時后才收到信息的話, 很遺憾, 沒了處理函數, 直接忽略. 我建議定時器設定到5秒. 當然, 隨便你. 一定要保證成功收到第一個node的find_node回復, 不然失敗, 就沒法繼續find_node了.即: 認識不到第一個朋友, 就別想認識第二個朋友.

id: 就是自身node ID了, 是node_id()函數生成的哈, 樣子絕不是DHT協議例子中的樣子, 這主要是為了方便演示而已

target: 這個也是自身的node ID, 作用是問某node離我最近的都有哪些node.

收到對方回復后, 把那key為nodes給解析出來, 按DHT協議說的, 每個node是以4字節ip+2字節port+20字節node ID組成, 那么nodes的字節數就會是26的倍數. "解碼"node和"編碼"node的Python代碼如下:

  1. from struct import unpack  
  2.  
  3. def num_to_dotted(n):  
  4.     d = 256 * 256 * 256 
  5.     q = []  
  6.     while d > 0:  
  7.         m, n = divmod(n, d)  
  8.         q.append(str(m))  
  9.         d /= 256 
  10.     return '.'.join(q)  
  11.  
  12. def decode_nodes(nodes):  
  13.     n = []  
  14.     nrnodes = len(nodes) / 26 
  15.     nodes = unpack("!" + "20sIH" * nrnodes, nodes)  
  16.     for i in range(nrnodes):  
  17.         nid, ip, port = nodes[i * 3], num_to_dotted(nodes[i * 3 + 1]), nodes[i * 3 + 2]  
  18.         n.append((nid, ip, port))  
  19.     return n  
  20.  
  21. decode_nodes函數的反作用函數如下:  
  22. def dotted_to_num(ip):  
  23.     hexn = ''.join(["%02X" % long(i) for i in ip.split('.')])  
  24.     return long(hexn, 16)  
  25.  
  26. def encode_nodes(nodes):  
  27.     n = []  
  28.     for node in nodes:  
  29.         n.extend([node.nid, dotted_to_num(node.ip), node.port])  
  30.     return pack("!" + "20sIH" * len(nodes), *n) 

解析出來后, 插入到路由表里, 然后使用find_node繼續向剛解析出來的node進行請求, target還是自身node ID, 以此循環. 這樣就能認識很多很多的node啦. 細節就不說了, 自己看著辦.

 

第三步, 實現DHT服務器端, 協議文檔說得很清楚了, 我只列出幾個需要注意的問題:

1, 服務器端得實現處理node發來的ping, find_node, get_peers, announce_peer請求.

2, 回應信息里的t的值是對方的t值, 不是自己隨便寫的.

3, 最好要實現那個token機制, 這樣就減少被搗亂的幾率, 此token就按協議那種方式就行, 每5分鐘變換一次, 10分鐘內的有效.

4, 一定要記得前面說的那句"當該bucket負責的node有請求, 回應操作; 刪除node; 添加node; 更新node; 等這些操作時, 那么就刷新該bucket".

5, 由于是做DHT爬蟲, 所以處理get_peers請求和find_node請求差不多一樣, 都是返回最近的node. 當然, 你閑得蛋疼的話, 可以來得標準點, 做能返回peers那種, 不過, 沒必要.

6, announce_peer請求里的port就是對方提供下載種子的端口, 監聽于TCP, 不是DHT連接的端口. 還有請求消息里的id就僅僅指的是對方的node ID, 我看博客園某人寫的文章說是對方的peer ID, 我表示很不解.

 

第四步, 定時刷新路由表

按協議所說, 過一段時間后, 路由表里的node不全都是活躍了, 所以要定時刷新路由表. 說下大概思路, 遍歷路由表中的bucket列表, 看看bucket的last_accessed是不是超過了比如說15分鐘, 如果超過了, 說明有可能不"新鮮"了, 那么從該bucket隨機選擇一個node, 向該node發送find_node操作, 接著就不管了. 筆者為了簡單, 就采用這么簡單的方式了, 沒有去確認可疑node是否還"活"著. 你可以嚴格按照協議文檔那么寫.

 

你可能會問的問題:

1, 怎么知道一個資源的下載速度?

答: 有句話這么說: 下載人數越多, 下載速度越快. 那么, 如果某一個資源的infohash出現的announce_peer次數越高, 那么就說明下載人數就越多, 人數越多就越快. 這個下載速度就沒法用絕對速度表示, 不過可以使用相對速度.

2, 怎么在眾多的資源中過濾出影視資源?

答: 得到種子, 如果有files字段話, 遍歷它進行正則匹配, 看看有木有后綴名是rmvb, avi, mp4等什么的, 如果有, 那它大部分情況就是影視了. 如果沒有files字段, 就對name字段進行正則匹配吧.

3, 為什么那些影視資源總是些"很黃很暴力"?

答: 這個就不是很清楚了, 我想, 使用BT的人大多數都是些擼管男吧.

4, infohash這個詞是根據什么而來的?

答: 種子文件中info字段的hash值

5, 如何認識更多的node?

答: 多開啟幾個node實例.

6, 什么情況下, 對方把我給加入到對方的路由表里?

答: 當你向對方find_node時. 也許你的ping, get_peers也能讓對方把你添加到路由表里. 同理, 當你接到ping, find_node, get_peers時, 就把對方給添加到路由表里, 至少收到find_node請求時, 就要把對方給添加到路由表里.

7, 如何長期保存node?

答: 數據庫, 文件都行, 我不建議長期保存node, 你只要一直在線, 使用內存存儲最好不過了, 速度快, 代碼簡單.

原文鏈接:http://www.cnblogs.com/52web/p/How-to-write-a-DHT-crawler.html

責任編輯:林師授 來源: 博客園
相關推薦

2017-11-15 12:57:57

爬蟲爬取數據分析

2023-08-02 08:00:00

JavaScriptWeb

2010-09-30 11:17:22

2019-10-30 15:27:28

Google谷歌Alphabet

2022-10-18 22:20:36

CSS矩形border

2015-04-15 10:29:38

Linux 4.0

2009-11-24 09:31:38

2013-04-22 09:46:37

軟件項目開發

2015-07-28 17:28:15

程序員技能

2022-03-02 09:40:26

微軟Windows 8ASCII 貓

2016-05-19 13:44:53

云計算大數據

2014-03-04 09:55:23

2017-09-12 12:13:57

夢想 咸魚

2018-02-05 10:43:16

旅行青蛙

2009-11-28 20:09:36

2020-07-15 07:40:20

Linux命令JavaScript

2022-10-20 07:43:46

2010-04-19 11:53:28

富士康

2009-09-11 09:18:46

互聯網尷尬信鴿

2023-12-18 08:42:49

Cat.1窄帶通信
點贊
收藏

51CTO技術棧公眾號

日韩欧美国产一区在线观看| 中文字幕在线不卡一区| 2019av中文字幕| 亚洲黄色小说视频| 欧美高清免费| 亚洲成在人线在线播放| 日韩色妇久久av| 午夜精品一区二区三| 亚洲欧美日韩精品一区二区| 日日骚久久av| 欧美精品欧美极品欧美激情| 久久天天久久| 同产精品九九九| 一本久久a久久精品vr综合| www黄色网址| 久久精品国产色蜜蜜麻豆| 久久人人97超碰精品888| 国产又黄又粗又猛又爽的| 黄色成人美女网站| 欧美日韩在线直播| 黄www在线观看| 欧美xxxx少妇| 亚洲三级小视频| 黄色小网站91| 亚洲卡一卡二卡三| 激情欧美一区二区| 国产精品第3页| www.国产高清| 一区在线视频观看| 久久亚洲私人国产精品va| 免费看黄色av| 久久成人高清| 亚洲乱码国产乱码精品精| 黄色av电影网站| 久久久国产精品入口麻豆| 欧美三级三级三级| 999香蕉视频| av日韩亚洲| 狠狠干狠狠久久| 国产 日韩 亚洲 欧美| 成人免费高清| 亚洲日本乱码在线观看| 翔田千里亚洲一二三区| 国产在线小视频| 久久你懂得1024| 乱色588欧美| 亚洲 国产 欧美 日韩| 国产美女视频一区| 亚洲永久在线观看| av观看在线免费| 国产麻豆91精品| 97自拍视频| 亚洲第一天堂在线观看| 国产精品88av| 成人在线观看网址| 欧美 日韩 中文字幕| 懂色av一区二区三区免费观看| 91久久精品www人人做人人爽| 国产伦子伦对白视频| 激情久久五月天| 91嫩草在线| 黄色av小说在线观看| 成人午夜电影久久影院| 精品国产综合久久| 日本五码在线| 欧美极品xxx| 在线观看一区欧美| 18videosex性欧美麻豆| 亚洲国产日韩一区二区| 一区二区传媒有限公司| 巨茎人妖videos另类| 欧美性猛交xxxxxxxx| 精品亚洲一区二区三区四区| 高清一区二区| 亚洲第一色中文字幕| 国产偷人妻精品一区| 精品在线播放| 久久精品国产91精品亚洲| 欧美成人三级视频| 99av国产精品欲麻豆| 国产成人精品视频| 国产精品久久久久久69| 成人av资源在线观看| 欧美日韩综合久久| 国产写真视频在线观看| 亚洲午夜精品一区二区三区他趣| av免费观看网| 欧美视频免费看| 精品福利视频一区二区三区| 欧美特黄一区二区三区| 婷婷综合五月| 538国产精品视频一区二区| 免费看av在线| 不卡一卡二卡三乱码免费网站| 免费久久99精品国产自| 里番在线观看网站| 精品国产91乱高清在线观看| 91日韩视频在线观看| 精品视频成人| 国产性色av一区二区| 欧美成人一二三区| 日韩经典一区二区| 国产精品theporn88| 99中文字幕一区| 亚洲.国产.中文慕字在线| 日本在线观看免费视频| 啪啪激情综合网| 不卡伊人av在线播放| 天堂网视频在线| 福利一区二区在线观看| 亚洲免费在线精品一区| 日本蜜桃在线观看视频| 日韩午夜小视频| 手机看片国产日韩| 国产亚洲激情| 91视频最新| 日本视频在线| 91国产免费看| theav精尽人亡av| 欧美日韩91| 成人激情综合网| 国产在线91| 天天av天天翘天天综合网色鬼国产| 国产永久免费网站| 欧美裸体在线版观看完整版| 亚洲18私人小影院| 亚洲欧美强伦一区二区| 亚洲欧洲av在线| 天天爽人人爽夜夜爽| 亚洲亚洲免费| 欧美一二三视频| 蜜臀av午夜精品| 夜夜揉揉日日人人青青一国产精品| 亚洲精品第三页| 日韩大片在线播放| 国产精品午夜视频| 啊v在线视频| 日本韩国精品在线| 亚洲区免费视频| 久久一区欧美| 日本一区二区三区免费观看| 伊人久久综合一区二区| 亚洲国产精品成人精品| 久久精品欧美一区二区| 成人自拍视频在线| 国产成人永久免费视频| 91成人福利| 久久久中文字幕| 手机看片一区二区| 精品久久久久久久久久| 国产精品无码在线| 国产一区二区三区久久久久久久久| 国产色综合一区二区三区| sis001亚洲原创区| 亚洲黄色av网站| 免费观看成人毛片| 国产日韩av一区| 香港日本韩国三级网站| 欧美韩日一区| 97netav| 2021中文字幕在线| 日韩精品黄色网| 日韩国产成人在线| 中文乱码免费一区二区| www.com久久久| 欧美午夜影院| 久久青青草综合| 欧美日韩激情电影| 久久精品99无色码中文字幕| 亚洲h视频在线观看| 精品久久久久久久久中文字幕| 草草影院第一页| 美女在线观看视频一区二区| 福利网在线观看| 国产日韩三级| 国产精品久久久久av免费| a级影片在线| 日韩成人在线视频网站| 午夜精品久久久久久久蜜桃| 国产精品精品国产色婷婷| 久久久久亚洲av无码网站| 国产欧美另类| 亚洲欧洲在线一区| 岛国av一区| 国产精品免费久久久久影院| a级在线观看| 亚洲欧美国内爽妇网| 97人妻精品一区二区三区视频| 亚洲国产综合视频在线观看| 五级黄高潮片90分钟视频| 麻豆精品久久精品色综合| 精品少妇人欧美激情在线观看| 国产一区二区在线| 91大片在线观看| 婷婷六月国产精品久久不卡| 成人97在线观看视频| 色鬼7777久久| 日韩免费电影一区| 国产在线一级片| 亚洲成人在线网站| 182在线观看视频| 99久久精品国产导航| 亚洲综合激情视频| 麻豆精品网站| 国产一区二区四区| 91超碰成人| 天堂资源在线亚洲视频| 国产精品45p| 成人午夜高潮视频| 国产精品毛片久久久久久久久久99999999| 欧美国产极速在线| 欧美a在线看| 亚洲精品视频免费| 韩国av免费在线| 91精品国产综合久久久蜜臀粉嫩| 无码人妻av一区二区三区波多野| 亚洲成在人线免费| 好吊日在线视频| 国产精品久久久久精k8 | 拔插拔插海外华人免费| 日本电影一区二区| 欧美日韩在线观看一区二区三区| 极品束缚调教一区二区网站 | 免费观看成年人视频| 7777精品伊人久久久大香线蕉的 | 欧美综合在线视频观看| 国产一区二区三区四区五区在线 | 日本在线xxx| 欧美日韩第一区| 日本a在线天堂| 亚洲高清资源在线观看| 一区二区三区四区免费视频| 精品视频免费| 日韩一区不卡| 精品理论电影| 午夜欧美一区二区三区免费观看| 国产亚洲一区二区三区啪| 久久精品美女| 亚洲v天堂v手机在线| 久久国产精品高清| 亚洲8888| 日韩国产美国| 欧美三级美国一级| 日韩av图片| 成人羞羞动漫| 亚洲一区3d动漫同人无遮挡| 日韩毛片视频| 在线视频欧美一区| 五月久久久综合一区二区小说| 亚洲视频在线二区| 亚洲91中文字幕无线码三区| 一区二区在线中文字幕电影视频| 久久一区91| 警花观音坐莲激情销魂小说| 午夜日韩激情| 欧美黑人经典片免费观看| 日韩一级不卡| 男操女免费网站| 国产综合色在线视频区| 天天爽夜夜爽视频| 成人av免费网站| 最近中文字幕免费视频| 亚洲国产精品二十页| 欧美风情第一页| 夜夜嗨av一区二区三区中文字幕| xxxxxx国产| 色老汉av一区二区三区| 一区二区三区精彩视频| 欧美一区国产二区| 亚洲日本国产精品| 在线观看91久久久久久| 精产国品自在线www| 欧美激情一级欧美精品| 无遮挡在线观看| 国产欧美一区二区三区在线| 欧美视频三区| 久久亚洲国产精品日日av夜夜| av亚洲免费| 三级在线免费观看| 另类国产ts人妖高潮视频| 狠狠干狠狠操视频| 成人ar影院免费观看视频| 性の欲びの女javhd| 亚洲美女免费在线| 特级西西444www大精品视频免费看 | 亚洲欧洲久久| 亚洲午夜在线| 日韩在线第三页| 国产91丝袜在线播放| 一级片视频免费看| 亚洲黄色尤物视频| 久久久久久久亚洲| 日韩美一区二区三区| 国产专区在线播放| 欧美大片免费看| 播放一区二区| 国产精品 日韩| 久久亚洲国产| 干日本少妇首页| 国产成人精品午夜视频免费| 乐播av一区二区三区| 亚洲一区二区av在线| 亚洲图片在线播放| 日韩国产欧美精品一区二区三区| 黄色精品免费看| 国产成人91久久精品| 国产成人aa在线观看网站站| 自拍亚洲欧美老师丝袜| 久久深夜福利| 国产精品手机在线观看| 国产精品久久久久久久久久免费看 | 国产一区清纯| 在线视频一二区| 国产精品污www在线观看| 好吊操这里只有精品| 欧美一区二区国产| 日本高清视频在线观看| 国产成人综合久久| 色老板在线视频一区二区| 成年人深夜视频| 激情六月婷婷久久| 少妇的滋味中文字幕bd| 一本久久精品一区二区| 天天干天天插天天操| 欧美激情xxxx| 亚洲91网站| 青青视频免费在线| 国产一区二区三区免费在线观看| 毛片视频免费播放| 欧美亚男人的天堂| 黄色软件在线| 国产精品99导航| 国产一区2区| 妓院一钑片免看黄大片| 久久美女高清视频| 日韩欧美在线观看免费| 亚洲精品在线观看www| 麻豆蜜桃在线观看| 久久精彩视频| 久久av一区| 久久国产柳州莫菁门| 在线看日韩精品电影| 啊v在线视频| 国产日韩欧美日韩大片| 93在线视频精品免费观看| 国产又黄又猛的视频| 亚洲欧美经典视频| 国产成人精品一区二三区四区五区| 久久天天躁狠狠躁夜夜爽蜜月| 99久久99九九99九九九| 警花观音坐莲激情销魂小说| 国产成人综合精品三级| 国产真人真事毛片| 亚洲激情在线观看| 性欧美videohd高精| 日本一区二区三区免费看| 免费成人美女在线观看| 亚洲色图100p| 日韩区在线观看| 新版的欧美在线视频| 日本不卡一二三区| 久久精品国产免费| 四虎免费在线视频| 亚洲国内精品在线| 美女福利一区二区| 中文字幕剧情在线观看一区| 国产综合色视频| 久久国产精品系列| 中文字幕日韩专区| 亚洲第一二区| 欧美性大战久久久久xxx| 欧美高清一级片在线观看| 国产强伦人妻毛片| 国产+人+亚洲| 日韩88av| av电影在线播放| 欧美性色综合网| 日本欧美电影在线观看| 欧美精品久久久| 国产综合成人久久大片91| 日韩三级视频在线播放| 国产亚洲免费的视频看| 精品久久免费| 97在线免费公开视频| 亚洲欧美日韩在线| 视频三区在线观看| 91牛牛免费视频| 香蕉国产精品偷在线观看不卡| 国产午夜精品理论片| 亚洲国产精品悠悠久久琪琪| 91精品国产66| 黄色一级在线视频| 日韩码欧中文字| 日av在线播放| 91精品天堂| 理论片日本一区| 中文字幕一区在线播放| 欧美巨大黑人极品精男| 国产亚洲电影| 一女三黑人理论片在线|