您現在的位置: 365建站網 > 365學習 > Python網絡爬蟲原理(代理/超時/重定向/Proxy/headers設置/httplib/urllib實現)

Python網絡爬蟲原理(代理/超時/重定向/Proxy/headers設置/httplib/urllib實現)

文章來源:365jz.com     點擊數:788    更新時間:2018-01-31 11:35   參與評論

初識網絡爬蟲

從本章開始,將正式涉及Python爬蟲的開發。本章主要分為兩個部分:一部分是網絡爬蟲的概述,幫助大家詳細了解網絡爬蟲;另一部分是HTTP請求的Python實現,幫助大家了解Python中實現HTTP請求的各種方式,以便具備編寫HTTP網絡程序的能力。

3.1 網絡爬蟲概述

本節正式進入Python爬蟲開發的專題,接下來從網絡爬蟲的概念、用處與價值和結構等三個方面,讓大家對網絡爬蟲有一個基本的了解。

3.1.1 網絡爬蟲及其應用

隨著網絡的迅速發展,萬維網成為大量信息的載體,如何有效地提取并利用這些信息成為一個巨大的挑戰,網絡爬蟲應運而生。網絡爬蟲(又被稱為網頁蜘蛛、網絡機器人),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。下面通過圖3-1展示一下網絡爬蟲在互聯網中起到的作用:

網絡爬蟲按照系統結構和實現技術,大致可以分為以下幾種類型:通用網絡爬蟲、聚焦網絡爬蟲、增量式網絡爬蟲、深層網絡爬蟲。

實際的網絡爬蟲系統通常是幾種爬蟲技術相結合實現的。

搜索引擎(Search Engine),例如傳統的通用搜索引擎baidu、

Yahoo和Google等,是一種大型復雜的網絡爬蟲,屬于通用性網絡爬蟲的范疇。但是通用性搜索引擎存在著一定的局限性:

1)不同領域、不同背景的用戶往往具有不同的檢索目的和需求,通用搜索引擎所返回的結果包含大量用戶不關心的網頁。

圖3-1 網絡爬蟲

2)通用搜索引擎的目標是盡可能大的網絡覆蓋率,有限的搜索引擎服務器資源與無限的網絡數據資源之間的矛盾將進一步加深。

3)萬維網數據形式的豐富和網絡技術的不斷發展,圖片、數據庫、音頻、視頻多媒體等不同數據大量出現,通用搜索引擎往往對這些信息含量密集且具有一定結構的數據無能為力,不能很好地發現和獲取。

4)通用搜索引擎大多提供基于關鍵字的檢索,難以支持根據語義信息提出的查詢。

為了解決上述問題,定向抓取相關網頁資源的聚焦爬蟲應運而生。

聚焦爬蟲是一個自動下載網頁的程序,它根據既定的抓取目標,有選擇地訪問萬維網上的網頁與相關的鏈接,獲取所需要的信息。與通用爬蟲不同,聚焦爬蟲并不追求大的覆蓋,而將目標定為抓取與某一特定主題內容相關的網頁,為面向主題的用戶查詢準備數據資源。

說完了聚焦爬蟲,接下來再說一下增量式網絡爬蟲。增量式網絡爬蟲是指對已下載網頁采取增量式更新和只爬行新產生的或者已經發生變化網頁的爬蟲,它能夠在一定程度上保證所爬行的頁面是盡可能新的頁面。和周期性爬行和刷新頁面的網絡爬蟲相比,增量式爬蟲只會在需要的時候爬行新產生或發生更新的頁面,并不重新下載沒有發生變化的頁面,可有效減少數據下載量,及時更新已爬行的網頁,減小時間和空間上的耗費,但是增加了爬行算法的復雜度和實現難度。

例如:想獲取趕集網的招聘信息,以前爬取過的數據沒有必要重復爬取,只需要獲取更新的招聘數據,這時候就要用到增量式爬蟲。

最后說一下深層網絡爬蟲。Web頁面按存在方式可以分為表層網頁和深層網頁。表層網頁是指傳統搜索引擎可以索引的頁面,以超鏈接可以到達的靜態網頁為主構成的Web頁面。深層網絡是那些大部分內容不能通過靜態鏈接獲取的、隱藏在搜索表單后的,只有用戶提交一些關鍵詞才能獲得的Web頁面。例如用戶登錄或者注冊才能訪問的頁面??梢韵胂筮@樣一個場景:爬取貼吧或者論壇中的數據,必須在用戶登錄后,有權限的情況下才能獲取完整的數據。

本書除了通用性爬蟲不會涉及之外,聚焦爬蟲、增量式爬蟲和深層網絡爬蟲的具體運用都會進行講解。下面展示一下網絡爬蟲實際運用的一些場景:

1)常見的BT網站,通過爬取互聯網的DHT網絡中分享的BT種子信息,提供對外搜索服務。例如http://www.cilisou.cn/,如圖3-2所示。

圖3-2 磁力搜網站首頁

2)一些云盤搜索網站,通過爬取用戶共享出來的云盤文件數據,對文件數據進行分類劃分,從而提供對外搜索服務。例如http://www.pansou.com/,如圖3-3所示。


圖3-3 盤搜網站首頁

3.1.2 網絡爬蟲結構

下面用一個通用的網絡爬蟲結構來說明網絡爬蟲的基本工作流程,如圖3-4所示。

圖3-4 網絡爬蟲結構

網絡爬蟲的基本工作流程如下:

1)首先選取一部分精心挑選的種子URL。

2)將這些URL放入待抓取URL隊列。

3)從待抓取URL隊列中讀取待抓取隊列的URL,解析DNS,并且得到主機的IP,并將URL對應的網頁下載下來,存儲進已下載網頁庫中。此外,將這些URL放進已抓取URL隊列。

4)分析已抓取URL隊列中的URL,從已下載的網頁數據中分析出其他URL,并和已抓取的URL進行比較去重,最后將去重過的URL放入待抓取URL隊列,從而進入下一個循環。

這便是一個基本的通用網絡爬蟲框架及其工作流程,在之后的章節我們會用Python實現這種網絡爬蟲結構。

3.2 HTTP請求的Python實現

通過上面的網絡爬蟲結構,我們可以看到讀取URL、下載網頁是每一個爬蟲必備而且關鍵的功能,這就需要和HTTP請求打交道。接下來講解Python中實現HTTP請求的三種方式:urllib2/urllib、httplib/urllib以及Requests。

3.2.1 urllib2/urllib實現

urllib2和urllib是Python中的兩個內置模塊,要實現HTTP功能,實現方式是以urllib2為主,urllib為輔。

1.首先實現一個完整的請求與響應模型

urllib2提供一個基礎函數urlopen,通過向指定的URL發出請求來獲取數據。最簡單的形式是:

import urllib2 response=urllib2.urlopen('http://www.zhihu.com')
HTML=response.read()
print html

其實可以將上面對http://www.zhihu.com的請求響應分為兩步,一步是請求,一步是響應,形式如下:

import urllib2 # 請求

request=urllib2.Request('http://www.zhihu.com')
# 響應

response = urllib2.urlopen(request)
html=response.read()
print html

上面這兩種形式都是GET請求,接下來演示一下POST請求,其實大同小異,只是增加了請求數據,這時候用到了urllib。示例如下:

import urllib
import urllib2 url = 'http://www.xxxxxx.com/login'
postdata = {'username' : 'qiye', 'password' : 'qiye_pass'} # info 需要被編碼為urllib2能理解的格式,這里用到的是urllib
data = urllib.urlencode(postdata)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
html = response.read()

但是有時會出現這種情況:即使POST請求的數據是對的,但是服務器拒絕你的訪問。這是為什么呢問題出在請求中的頭信息,服務器會檢驗請求頭,來判斷是否是來自瀏覽器的訪問,這也是反爬蟲的常用手段。

2.請求頭headers處理

將上面的例子改寫一下,加上請求頭信息,設置一下請求頭中的

User-Agent域和Referer域信息。

import urllib
import urllib2 url = 'http://www.xxxxxx.com/login'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
referer='http://www.xxxxxx.com/'
postdata = {'username' : 'qiye',

'password' : 'qiye_pass'} # 將user_agent,referer寫入頭信息

headers={'User-Agent':user_agent,'Referer':referer} data = urllib.urlencode(postdata)
req = urllib2.Request(url, data,headers)
response = urllib2.urlopen(req)
html = response.read()

也可以這樣寫,使用add_header來添加請求頭信息,修改如下:

import urllib
import urllib2 url = 'http://www.xxxxxx.com/login'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
referer='http://www.xxxxxx.com/'
postdata = {'username' : 'qiye', 'password' : 'qiye_pass'} data = urllib.urlencode(postdata)
req = urllib2.Request(url)
# 將user_agent,referer寫入頭信息

req.add_header('User-Agent',user_agent)
req.add_header('Referer',referer)
req.add_data(data)
response = urllib2.urlopen(req)
html = response.read()

 

print item.name+':'+item.value

但是有時候會遇到這種情況,我們不想讓urllib2自動處理,我們想自己添加Cookie的內容,可以通過設置請求頭中的Cookie域來做:

import urllib2 opener = urllib2.build_opener()
opener.addheaders.append( ( 'Cookie', 'email=' + "xxxxxxx@163.com" ) )
req = urllib2.Request( "http://www.zhihu.com/" )
response = opener.open(req)
print response.headers
retdata = response.read()

4.Timeout設置超時

在Python2.6之前的版本,urllib2的API并沒有暴露Timeout的設置,要設置Timeout值,只能更改Socket的全局Timeout值。示例如下:

import urllib2 import socket
socket.setdefaulttimeout(10) # 10 秒鐘后超時

urllib2.socket.setdefaulttimeout(10) # 另一種方式

在Python2.6及新的版本中,urlopen函數提供了對Timeout的設置,示例如下:

import urllib2 request=urllib2.Request('http://www.zhihu.com')
response = urllib2.urlopen(request,timeout=2)
html=response.read()
print html

5.獲取HTTP響應碼

對于200OK來說,只要使用urlopen返回的response對象的

getcode()方法就可以得到HTTP的返回碼。但對其他返回碼來說,

urlopen會拋出異常。這時候,就要檢查異常對象的code屬性了,示例如下:

import urllib2 try:
response = urllib2.urlopen('http://www.google.com')
print response
except urllib2.HTTPError as e:
if hasattr(e, 'code'):
print 'Error code:',e.code

6.重定向

urllib2默認情況下會針對HTTP 3XX返回碼自動進行重定向動作。要檢測是否發生了重定向動作,只要檢查一下Response的URL

和Request的URL是否一致就可以了,示例如下:

import urllib2 response = urllib2.urlopen('http://www.zhihu.cn')
isRedirected = response.geturl() == 'http://www.zhihu.cn'

如果不想自動重定向,可以自定義HTTPRedirectHandler類,示例如下:

import urllib2 class RedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_301(self, req, fp, code, msg, headers):
pass
def http_error_302(self, req, fp, code, msg, headers):
result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
result.status = code
result.newurl = result.geturl()
return result
opener = urllib2.build_opener(RedirectHandler)
opener.open('http://www.zhihu.cn')

7.Proxy的設置

在做爬蟲開發中,必不可少地會用到代理。urllib2默認會使用環境變量http_proxy來設置HTTP Proxy。但是我們一般不采用這種方式,

而是使用ProxyHandler在程序中動態設置代理,示例代碼如下:

import urllib2 proxy = urllib2.ProxyHandler({'http': '127.0.0.1:8087'})
opener = urllib2.build_opener([proxy,])
urllib2.install_opener(opener)
response = urllib2.urlopen('http://www.zhihu.com/')
print response.read()

這里要注意的一個細節,使用urllib2.install_opener()會設置

urllib2的全局opener,之后所有的HTTP訪問都會使用這個代理。這樣使用會很方便,但不能做更細粒度的控制,比如想在程序中使用兩個不同的Proxy設置,這種場景在爬蟲中很常見。比較好的做法是不使用install_opener去更改全局的設置,而只是直接調用opener的open方法代替全局的urlopen方法,修改如下:

import urllib2 proxy = urllib2.ProxyHandler({'http': '127.0.0.1:8087'})
opener = urllib2.build_opener(proxy,)
response = opener.open("http://www.zhihu.com/")
print response.read()

3.2.2 httplib/urllib實現

httplib模塊是一個底層基礎模塊,可以看到建立HTTP請求的每一步,但是實現的功能比較少,正常情況下比較少用到。在Python爬蟲開發中基本上用不到,所以在此只是進行一下知識普及。下面介紹一下常用的對象和函數:

·創建HTTPConnection對象:class httplib.HTTPConnection(host[,port[,strict[,timeout[,source_address]]]])。

·發送請求:HTTPConnection.request(method,url[,body[,headers]])。

·獲得響應:HTTPConnection.getresponse()。

·讀取響應信息:HTTPResponse.read([amt])。

·獲得指定頭信息:HTTPResponse.getheader(name[,default])。

·獲得響應頭(header,value)元組的列表:

HTTPResponse.getheaders()。

·獲得底層socket文件描述符:HTTPResponse.fileno()。

·獲得頭內容:HTTPResponse.msg。

·獲得頭http版本:HTTPResponse.version。

·獲得返回狀態碼:HTTPResponse.status。

·獲得返回說明:HTTPResponse.reason。

接下來演示一下GET請求和POST請求的發送,首先是GET請求的示例,如下所示:

import httplib
conn =None
try:
conn = httplib.HTTPConnection("www.zhihu.com")
conn.request("GET", "/")
response = conn.getresponse()
print response.status, response.reason
print '-' * 40 headers = response.getheaders()
for h in headers:
print h
print '-' * 40 print response.msg
except Exception,e:
print e
finally:
if conn:
conn.close()

POST請求的示例如下:

import httplib, urllib
conn = None
try:
params = urllib.urlencode({'name': 'qiye', 'age': 22})
headers = {"Content-type": "application/x-www-form-urlencoded"
, "Accept": "text/plain"} conn = httplib.HTTPConnection("www.zhihu.com", 80, timeout=3)
conn.request("POST", "/login", params, headers)
response = conn.getresponse()
print response.getheaders() # 獲取頭信息

print response.status
print response.read()
except Exception, e:
print e
finally:
if conn:
conn.close()

3.2.3 更人性化的Requests

Python中Requests實現HTTP請求的方式,是本人極力推薦的,也是在Python爬蟲開發中最為常用的方式。Requests實現HTTP請求非常簡單,操作更加人性化。

Requests庫是第三方模塊,需要額外進行安裝。Requests是一個開源庫,源碼位于GitHub:https://github.com/kennethreitz/requests,希望大家多多支持作者。使用Requests庫需要先進行安裝,一般有兩種安裝方式:

·使用pip進行安裝,安裝命令為:pip install requests,不過可能不是最新版。

·直接到GitHub上下載Requests的源代碼,下載鏈接為:https://github.com/kennethreitz/requests/releases。將源代碼壓縮包進行解壓,然后進入解壓后的文件夾,運行setup.py文件即可。

如何驗證Requests模塊安裝是否成功呢?在Python的shell中輸入import requests,如果不報錯,則是安裝成功。如圖3-5所示。


圖3-5 驗證Requests安裝

1.首先還是實現一個完整的請求與響應模型

以GET請求為例,最簡單的形式如下:

import requests

r = requests.get('http://www.baidu.com')
print r.content

大家可以看到比urllib2實現方式的代碼量少。接下來演示一下

POST請求,同樣是非常簡短,更加具有Python風格。示例如下:

import requests
postdata={'key':'value'} r = requests.post('http://www.xxxxxx.com/login',data=postdata)
print r.content

HTTP中的其他請求方式也可以用Requests來實現,示例如下:

·r=requests.put('http://www.xxxxxx.com/put',data={'key':'value'})

·r=requests.delete('http://www.xxxxxx.com/delete')

·r=requests.head('http://www.xxxxxx.com/get')

·r=requests.options('http://www.xxxxxx.com/get')

接著講解一下稍微復雜的方式,大家肯定見過類似這樣的URL:

http://zzk.cnblogs.com/s/ blogpost?Keywords=blog:qiyeboy&pageindex=1,就是在網址后面緊跟著“?”,“?”后面還有參數。那么這樣的GET請求該如何發送呢?肯定有人會說,直接將完

整的URL帶入即可,不過Requests還提供了其他方式,示例如下:

import requests
payload = {'Keywords': 'blog:qiyeboy','pageindex':1} r = requests.get('http://zzk.cnblogs.com/s/blogpost', params=payload)
print r.url

通過打印結果,我們看到最終的URL變成了:

http://zzk.cnblogs.com/s/blogpostKeywords=blog:qiyeboy&pageindex=1。

2.響應與編碼

還是從代碼入手,示例如下:

import requests
r = requests.get('http://www.baidu.com')
print 'content-->'+r.content
print 'text-->'+r.text
print 'encoding-->'+r.encoding
r.encoding='utf-8'
print 'new text-->'+r.text

其中r.content返回的是字節形式,r.text返回的是文本形式,

r.encoding返回的是根據HTTP頭猜測的網頁編碼格式。

輸出結果中:“text-->”之后的內容在控制臺看到的是亂碼,“encoding-->”之后的內容是ISO-8859-1(實際上的編碼格式是UTF-8),由于Requests猜測編碼錯誤,導致解析文本出現了亂碼。

Requests提供了解決方案,可以自行設置編碼格式,r.encoding=‘utf-8’設置成UTF-8之后,“new text-->”的內容就不會出現亂碼。但是這種手動的方式略顯笨拙,下面提供一種更加簡便的方式:chardet,這是一個非常優秀的字符串/文件編碼檢測模塊。安裝方式如下:

pip install chardet

安裝完成后,使用chardet.detect()返回字典,其中confidence

是檢測精確度,encoding是編碼形式。示例如下:

import requests
r = requests.get('http://www.baidu.com')
print chardet.detect(r.content)
r.encoding = chardet.detect(r.content)['encoding'] print r.text

直接將chardet探測到的編碼,賦給r.encoding實現解碼,r.text輸出就不會有亂碼了。

除了上面那種直接獲取全部響應的方式,還有一種流模式,示例

如下:

import requests
r = requests.get('http://www.baidu.com',stream=True)
print r.raw.read(10)

設置stream=True標志位,使響應以字節流方式進行讀取,

r.raw.read函數指定讀取的字節數。

3.請求頭headers處理

Requests對headers的處理和urllib2非常相似,在Requests的get

函數中添加headers參數即可。示例如下:

import requests
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers={'User-Agent':user_agent} r = requests.get('http://www.baidu.com',headers=headers)
print r.content

4.響應碼code和響應頭headers處理

獲取響應碼是使用Requests中的status_code字段,獲取響應頭使用Requests中的headers字段。示例如下:

import requests

r = requests.get('http://www.baidu.com')
if r.status_code == requests.codes.ok:
print r.status_code# 響應碼

print r.headers# 響應頭

print r.headers.get('content-type')# 推薦使用這種獲取方式,獲取其中的某個字段

print r.headers['content-type']# 不推薦使用這種獲取方式

else:
r.raise_for_status()

上述程序中,r.headers包含所有的響應頭信息,可以通過get函數獲取其中的某一個字段,也可以通過字典引用的方式獲取字典值,但是不推薦,因為如果字段中沒有這個字段,第二種方式會拋出異常,第一種方式會返回None。r.raise_for_status()是用來主動地產生一個異常,當響應碼是4XX或5XX時,raise_for_status()函數會拋出異常,而響應碼為200時,raise_for_status()函數返回None。

5.Cookie處理

如果響應中包含Cookie的值,可以如下方式獲取Cookie字段的值,示例如下:

import requests
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers={'User-Agent':user_agent} r = requests.get('http://www.baidu.com',headers=headers)
# 遍歷出所有的cookie字段的值

for cookie in r.cookies.keys():
print cookie+':'+r.cookies.get(cookie)

如果想自定義Cookie值發送出去,可以使用以下方式,示例如下:

import requests
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers={'User-Agent':user_agent} cookies = dict(name='qiye',age='10')
r = requests.get('http://www.baidu.com',headers=headers,cookies=cookies)
print r.text

還有一種更加高級,且能自動處理Cookie的方式,有時候我們不需要關心Cookie值是多少,只是希望每次訪問的時候,程序自動把Cookie的值帶上,像瀏覽器一樣。Requests提供了一個session的概念,在連續訪問網頁,處理登錄跳轉時特別方便,不需要關注具體細節。使用方法示例如下:

import Requests
loginUrl = 'http://www.xxxxxxx.com/login'
s = requests.Session()
#首先訪問登錄界面,作為游客,服務器會先分配一個cookie
r = s.get(loginUrl,allow_redirects=True)
datas={'name':'qiye','passwd':'qiye'}
#向登錄鏈接發送post請求,驗證成功,游客權限轉為會員權限

r = s.post(loginUrl, data=datas,allow_redirects= True)
print r.text

上面的這段程序,其實是正式做Python開發中遇到的問題,如果沒有第一步訪問登錄的頁面,而是直接向登錄鏈接發送Post請求,系統會把你當做非法用戶,因為訪問登錄界面時會分配一個Cookie,需要將這個Cookie在發送Post請求時帶上,這種使用Session函數處理Cookie的方式之后會很常用。

6.重定向與歷史信息

處理重定向只是需要設置一下allow_redirects字段即可,例如

r=requests.get(‘http://www.baidu.com’,allow_redirects=True)。將allow_redirects設置為True,則是允許重定向;設置為False,則是禁止重定向。如果是允許重定向,可以通過r.history字段查看歷史信息,即訪問成功之前的所有請求跳轉信息。示例如下:

import requests
r = requests.get('http://github.com')
print r.url
print r.status_code
print r.history

打印結果如下:

https:// github.com/ 200 (<Response [301]>,)

上面的示例代碼顯示的效果是訪問GitHub網址時,會將所有的HTTP請求全部重定向為HTTPS。

7.超時設置

超時選項是通過參數timeout來進行設置的,示例如下:

requests.get('http://github.com', timeout=2)

8.代理設置

使用代理Proxy,你可以為任意請求方法通過設置proxies參數來配置單個請求:

import requests
proxies = { "http": "http://0.10.1.10:3128", "https": "http://10.10.1.10:1080", } requests.get("http://example.org", proxies=proxies)

也可以通過環境變量HTTP_PROXY和HTTPS_PROXY來配置代

理,但是在爬蟲開發中不常用。你的代理需要使用HTTP Basic
Auth,可以使用http://user:password@host/語法:

proxies = { "http": "http://user:pass@10.10.1.10:3128/", }

小結

本章主要講解了網絡爬蟲的結構和應用,以及Python實現HTTP請求的幾種方法。希望大家對本章中的網絡爬蟲工作流程和Requests實現HTTP請求的方式重點吸收消化。

 

如對本文有疑問,請提交到交流論壇,廣大熱心網友會為你解答??! 點擊進入論壇


發表評論 (788人查看,0條評論)
請自覺遵守互聯網相關的政策法規,嚴禁發布色情、暴力、反動的言論。
用戶名: 驗證碼: 點擊我更換圖片
最新評論
------分隔線----------------------------
自拍偷拍福力视频,偷拍国际精品,麻豆一区福利电影,国产网红视频午夜福利,se视频大全,久久国产AV影院 小东西瞧你敏感的泛滥了| 久久不卡日韩美女| 日本黄页在线观看免费| 中文字幕在线观看2o18| 从前面动插图前入| 日本暴力强奷免费视频| china20岁高中生gay在线| 日本强伦姧人妻完整版| 美女被黑人巨大进入的视频| 久久婷婷大香萑太香蕉AV| 久久精品国产精品亚洲艾草网| 国内2018年午夜福利5678| 那一夜他把我做到喷水| 97热久久免费频精品99| 99热这里只有精品国产免费免费| 亚洲丁香婷婷综合久久| 精品视频国产狼友视频| 校花张开玉腿求我桶她| 高干病房玩弄人妻双飞| 天天摸天天做天天爽视频| 狠狠色噜噜狠狠狠狠色综合久| 日本免费专区在线观看中破初| 免费看女人的隐私超爽| 调教家政妇| 夜晚被公侵犯的人妻深田字幕| 国产香蕉尹人视频在线| 男生自慰gay网址| 一段污到湿的文字| 中日韩中文字幕无码一本| 孕妇被弄到高潮的视频| 2020亚洲国产精品无码| http://www.indaba-analytics.com