亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

基于Java HttpClient和Htmlparser實現網絡爬蟲代碼

2020-03-24 16:04:22
字體:
來源:轉載
供稿:網友
開發環境的搭建,在工程的 Build Path 中導入下載的Commons-httpClient3.1.Jar,htmllexer.jar 以及 htmlparser.jar 文件。圖 1. 開發環境搭建 HttpClient 基本類庫使用HttpClinet 提供了幾個類來支持 HTTP 訪問。下面我們通過一些示例代碼來熟悉和說明這些類的功能和使用。 HttpClient 提供的 HTTP 的訪問主要是通過 GetMethod 類和 PostMethod 類來實現的,他們分別對應了 HTTP Get 請求與 Http Post 請求。GetMethod使用 GetMethod 來訪問一個 URL 對應的網頁,需要如下一些步驟。
生成一個 HttpClinet 對象并設置相應的參數。
生成一個 GetMethod 對象并設置響應的參數。
用 HttpClinet 生成的對象來執行 GetMethod 生成的 Get 方法。
處理響應狀態碼。
若響應正常,處理 HTTP 響應內容。
釋放連接。清單 1 的代碼展示了這些步驟,其中的注釋對代碼進行了較詳細的說明。清單 1./* 1 生成 HttpClinet 對象并設置參數*/ HttpClient httpClient=new HttpClient(); //設置 Http 連接超時為5秒httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000); /*2 生成 GetMethod 對象并設置參數*/ GetMethod getMethod=new GetMethod(url); //設置 get 請求超時為 5 秒getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000); //設置請求重試處理,用的是默認的重試處理:請求三次getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); /*3 執行 HTTP GET 請求*/ try{ int statusCode = httpClient.executeMethod(getMethod); /*4 判斷訪問的狀態碼*/ if (statusCode != HttpStatus.SC_OK) System.err.println("Method failed: "+ getMethod.getStatusLine()); /*5 處理 HTTP 響應內容*/ //HTTP響應頭部信息,這里簡單打印 Header[] headers=getMethod.getResponseHeaders(); for(Header h: headers) System.out.println(h.getName()+" "+h.getValue());*/ //讀取 HTTP 響應內容,這里簡單打印網頁內容 byte[] responseBody = getMethod.getResponseBody();//讀取為字節數組System.out.println(new String(responseBody)); //讀取為 InputStream,在網頁內容數據量大時候推薦使用 InputStream response = getMethod.getResponseBodyAsStream();//catch (HttpException e) // 發生致命的異常,可能是協議不對或者返回的內容有問題 System.out.println("Please check your provided http address!");e.printStackTrace();catch (IOException e) // 發生網絡異常 e.printStackTrace(); } finally { /*6 .釋放連接*/ getMethod.releaseConnection(); } 這里值得注意的幾個地方是:設置連接超時和請求超時,這兩個超時的意義不同,需要分別設置。
響應狀態碼的處理。返回的結果可以為字節數組,也可以為 InputStream,而后者在網頁內容數據量較大的時候推薦使用。
在處理返回結果的時候可以根據自己的需要,進行相應的處理。如筆者是需要保存網頁
到本地,因此就可以寫一個 saveToLocaleFile(byte[] data, String filePath) 的方法,將字節數組保存成本地文件。后續的簡易爬蟲部分會有相應的介紹。PostMethod PostMethod 方法與 GetMethod 方法的使用步驟大體相同。但是由于 PostMethod 使用的是HTTP 的 Post 請求,因而請求參數的設置與 GetMethod 有所不同。在 GetMethod 中,請求的參數直接寫在 URL 里,一般以這樣形式出現:http://hostname:port//file name1=value1&name2=value …。請求參數是 name,value 對。比如我想得到百度搜索“Thinking In Java”的結果網頁,就可以使 GetMethod 的構造方法中的 url 為:http://www.baidu.com/s wd=Thinking+In+Java 。而 PostMethod 則可以模擬網頁里表單提交的過程,通過設置表單里 post 請求參數的值,來動態的獲得返回的網頁結果。清單 2 中的代碼展示了如何創建一個 Post 對象,并設置相應的請求參數。清單2PostMethod postMethod = new PostMethod("http://dict.cn/");postMethod.setRequestBody(new NameValuePair[]{new NameValuePair("q","java")}); HtmlParser 基本類庫使用HtmlParser 提供了強大的類庫來處理 Internet 上的網頁,可以實現對網頁特定內容的提取和修改。下面通過幾個例子來介紹 HtmlParser 的一些使用。這些例子其中的代碼,有部分用在了后面介紹的簡易爬蟲中。以下所有的代碼和方法都在在類 HtmlParser.Test.java 里,這是筆者編寫的一個用來測試 HtmlParser 用法的類。迭代遍歷網頁所有節點網頁是一個半結構化的嵌套文本文件,有類似 XML 文件的樹形嵌套結構。使用HtmlParser 可以讓我們輕易的迭代遍歷網頁的所有節點。清單 3 展示了如何來實現這個功能。
清單 3
// 循環訪問所有節點,輸出包含關鍵字的值節點public static void extractKeyWordText(String url, String keyword) { try { //生成一個解析器對象,用網頁的 url 作為參數 Parser parser = new Parser(url); //設置網頁的編碼,這里只是請求了一個 gb2312 編碼網頁 parser.setEncoding("gb2312"); //迭代所有節點, null 表示不使用 NodeFilter NodeList list = parser.parse(null); //從初始的節點列表跌倒所有的節點 processNodeList(list, keyword); } catch (ParserException e) { e.printStackTrace(); private static void processNodeList(NodeList list, String keyword) { //迭代開始 SimpleNodeIterator iterator = list.elements(); while (iterator.hasMoreNodes()) { Node node = iterator.nextNode(); //得到該節點的子節點列表 NodeList childList = node.getChildren(); //孩子節點為空,說明是值節點 if (null == childList) //得到值節點的值 String result = node.toPlainTextString(); //若包含關鍵字,則簡單打印出來文本 if (result.indexOf(keyword) != -1) System.out.println(result); } //end if //孩子節點不為空,繼續迭代該孩子節點 else processNodeList(childList, keyword); }//end else }//end wile } 上面的中有兩個方法:
private static void processNodeList(NodeList list, String keyword) 該方法是用類似深度優先的方法來迭代遍歷整個網頁節點,將那些包含了某個關鍵字的值節點的值打印出來。
public static void extractKeyWordText(String url, String keyword) 該方法生成針對 String 類型的 url 變量代表的某個特定網頁的解析器,調用 1中的方法實現簡單的遍歷。清單 3 的代碼展示了如何迭代所有的網頁,更多的工作可以在此基礎上展開。比如找到某個特定的網頁內部節點,其實就可以在遍歷所有的節點基礎上來判斷,看被迭代的節點是否滿足特定的需要。使用 NodeFilterNodeFilter 是一個接口,任何一個自定義的 Filter 都需要實現這個接口中的 boolean accept() 方法。如果希望迭代網頁節點的時候保留當前節點,則在節點條件滿足的情況下返回 true;否則返回 false。HtmlParse 里提供了很多實現了 NodeFilter 接口的類,下面就一些筆者所用到的,以及常用的 Filter 做一些介紹:對 Filter 做邏輯操作的 Fitler 有:AndFilter,NotFilter ,OrFilter,XorFilter。
這些 Filter 來組合不同的 Filter,形成滿足兩個 Filter 邏輯關系結果的 Filter。判斷節點的孩子,兄弟,以及父親節點情況的 Filter 有:HasChildFilterHasParentFilter,HasSiblingFilter。
判斷節點本身情況的 Filter 有 HasAttributeFilter:判讀節點是否有特定屬性;LinkStringFilter:判斷節點是否是具有特定模式 (pattern) url 的節點;
TagNameFilter:判斷節點是否具有特定的名字;NodeClassFilter:判讀節點是否是某個 HtmlParser 定義好的 Tag 類型。在 org.htmlparser.tags 包下有對應 Html標簽的各種 Tag,例如 LinkTag,ImgeTag 等。還有其他的一些 Filter 在這里不一一列舉了,可以在 org.htmlparser.filters 下找到。清單 4 展示了如何使用上面提到過的一些 filter 來抽取網頁中的 a 標簽里的 href屬性值, img 標簽里的 src 屬性值,以及 frame 標簽里的 src 的屬性值。清單4// 獲取一個網頁上所有的鏈接和圖片鏈接public static void extracLinks(String url) { try { Parser parser = new Parser(url); parser.setEncoding("gb2312");//過濾 frame 標簽的 filter,用來提取 frame 標簽里的 src 屬性所、表示的鏈接 NodeFilter frameFilter = new NodeFilter() { public boolean accept(Node node) { if (node.getText().startsWith("frame src=")) { return true; } else { return false; //OrFilter 來設置過濾 a 標簽, img 標簽和 frame 標簽,三個標簽是 or 的關系 OrFilte rorFilter = new OrFilter(new NodeClassFilter(LinkTag.class), newNodeClassFilter(ImageTag.class)); OrFilter linkFilter = new OrFilter(orFilter, frameFilter); //得到所有經過過濾的標簽 NodeList list = parser.extractAllNodesThatMatch(linkFilter); for (int i = 0; i list.size(); i++) { Node tag = list.elementAt(i); if (tag instanceof LinkTag)// a 標簽 LinkTag link = (LinkTag) tag; String linkUrl = link.getLink();//url String text = link.getLinkText();//鏈接文字 System.out.println(linkUrl + "**********" + text); else if (tag instanceof ImageTag)// img 標簽 ImageTag image = (ImageTag) list.elementAt(i); System.out.print(image.getImageURL() + "********");//圖片地址 System.out.println(image.getText());//圖片文字 else// frame 標簽//提取 frame 里 src 屬性的鏈接如 frame src="test.html"/ String frame = tag.getText(); int start = frame.indexOf("src="); frame = frame.substring(start); int end = frame.indexOf(" "); if (end == -1) end = frame.indexOf(" frame = frame.substring(5, end - 1); System.out.println(frame);} catch (ParserException e) { e.printStackTrace();} 簡單強大的 StringBean
如果你想要網頁中去掉所有的標簽后剩下的文本,那就是用 StringBean 吧。以下簡單的代碼可以幫你解決這樣的問題:清單5StringBean sb = new StringBean();sb.setLinks(false);//設置結果中去點鏈接sb.setURL(url);//設置你所需要濾掉網頁標簽的頁面 url System.out.println(sb.getStrings());//打印結果 HtmlParser 提供了強大的類庫來處理網頁,由于本文旨在簡單的介紹,因此只是將與筆者后續爬蟲部分有關的關鍵類庫進行了示例說明。感興趣的讀者可以專門來研究一下 HtmlParser 更為強大的類庫。簡易爬蟲的實現 HttpClient 提供了便利的 HTTP 協議訪問,使得我們可以很容易的得到某個網頁的源碼并保存在本地;HtmlParser 提供了如此簡便靈巧的類庫,可以從網頁中便捷的提取出指向其他網頁的超鏈接。筆者結合這兩個開源包,構建了一個簡易的網絡爬蟲。
爬蟲 (Crawler) 原理 學過數據結構的讀者都知道有向圖這種數據結構。如下圖所示,如果將網頁看成是圖中的某一個節點,而將網頁中指向其他網頁的鏈接看成是這個節點指向其他節點的邊,那么我們很容易將整個 Internet 上的網頁建模成一個有向圖。理論上,通過遍歷算法遍歷該圖,可以訪問到Internet 上的幾乎所有的網頁。最簡單的遍歷就是寬度優先以及深度優先。以下筆者實現的簡易爬蟲就是使用了寬度優先的爬行策略
圖 2. 網頁關系的建模圖 簡易爬蟲實現流程 在看簡易爬蟲的實現代碼之前,先介紹一下簡易爬蟲爬取網頁的流程。圖 3. 爬蟲流程圖 各個類的源碼以及說明對應上面的流程圖,簡易爬蟲由下面幾個類組成,各個類職責如下:Crawler.java:爬蟲的主方法入口所在的類,實現爬取的主要流程。LinkDb.java:用來保存已經訪問的 url 和待爬取的 url 的類,提供url出對入隊操作。Queue.java: 實現了一個簡單的隊列,在 LinkDb.java 中使用了此類。FileDownloader.java:用來下載 url 所指向的網頁。HtmlParserTool.java: 用來抽取出網頁中的鏈接。LinkFilter.java:一個接口,實現其 accept() 方法用來對抽取的鏈接進行過濾。下面是各個類的源碼,代碼中的注釋有比較詳細的說明。清單6 Crawler.javapackage com.ie; import java.util.Set;public class Crawler { /* 使用種子 url 初始化 URL 隊列*/ private void initCrawlerWithSeeds(String[] seeds) for(int i=0;i seeds.length;i++) LinkDB.addUnvisitedUrl(seeds[i]); /* 爬取方法*/ public void crawling(String[] seeds) LinkFilter filter = new LinkFilter(){ //提取以 http://www.twt.edu.cn 開頭的鏈接 public boolean accept(String url) { if(url.startsWith("http://www.twt.edu.cn")) return true; else return false; //初始化 URL 隊列 initCrawlerWithSeeds(seeds); //循環條件:待抓取的鏈接不空且抓取的網頁不多于 1000 while(!LinkDB.unVisitedUrlsEmpty()&&LinkDB.getVisitedUrlNum() =1000) //隊頭 URL 出對 String visitUrl=LinkDB.unVisitedUrlDeQueue(); if(visitUrl==null) continue; FileDownLoader downLoader=new FileDownLoader(); //下載網頁 downLoader.downloadFile(visitUrl); //該 url 放入到已訪問的 URL 中 LinkDB.addVisitedUrl(visitUrl); //提取出下載網頁中的 URL Set String links=HtmlParserTool.extracLinks(visitUrl,filter); //新的未訪問的 URL 入隊 for(String link:links) LinkDB.addUnvisitedUrl(link); //main 方法入口 public static void main(String[]args) Crawler crawler = new Crawler(); crawler.crawling(new String[]{"http://www.twt.edu.cn"});}清單7 LinkDb.javapackage com.ie;import java.util.HashSet;import java.util.Set; * 用來保存已經訪問過 Url 和待訪問的 Url 的類public class LinkDB { //已訪問的 url 集合 private static Set String visitedUrl = new HashSet String //待訪問的 url 集合 private static Queue String unVisitedUrl = new Queue String public static Queue String getUnVisitedUrl() { return unVisitedUrl; public static void addVisitedUrl(String url) { visitedUrl.add(url); public static void removeVisitedUrl(String url) { visitedUrl.remove(url); public static String unVisitedUrlDeQueue() { return unVisitedUrl.deQueue(); // 保證每個 url 只被訪問一次 public static void addUnvisitedUrl(String url) { if (url != null && !url.trim().equals("") && !visitedUrl.contains(url) && !unVisitedUrl.contians(url)) unVisitedUrl.enQueue(url); public static int getVisitedUrlNum() { return visitedUrl.size(); public static boolean unVisitedUrlsEmpty() { return unVisitedUrl.empty();清單8 Queue.java
package com.ie;import java.util.LinkedList; * 數據結構隊列public class Queue T { private LinkedList T queue=new LinkedList T public void enQueue(T t) queue.addLast(t); public T deQueue() return queue.removeFirst(); public boolean isQueueEmpty() return queue.isEmpty(); public boolean contians(T t) return queue.contains(t); public boolean empty() return queue.isEmpty();} 清單 9 FileDownLoader.java
package com.ie;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpException;import org.apache.commons.httpclient.HttpStatus;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.params.HttpMethodParams;public class FileDownLoader { /**根據 url 和網頁類型生成需要保存的網頁的文件名 *去除掉 url 中非文件名字符 public String getFileNameByUrl(String url,String contentType) url=url.substring(7);//remove http:// if(contentType.indexOf("html")!=-1)//text/html url= url.replaceAll("[// /:*| /"]", "_")+".html"; return url; else//如application/pdfreturn url.replaceAll("[// /:*| /"]", "_")+"."+ / contentType.substring(contentType.lastIndexOf("/")+1); /**保存網頁字節數組到本地文件 * filePath 為要保存的文件的相對地址 private void saveToLocal(byte[] data,String filePath) try { DataOutputStream out=new DataOutputStream(new FileOutputStream(new File(filePath))); for(int i=0;i data.length;i++) out.write(data[i]); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); /*下載 url 指向的網頁*/ public String downloadFile(String url) String filePath=null; /* 1.生成 HttpClinet 對象并設置參數*/ HttpClient httpClient=new HttpClient(); //設置 Http 連接超時 5s httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000); /*2.生成 GetMethod 對象并設置參數*/ GetMethod getMethod=new GetMethod(url); //設置 get 請求超時 5s getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000); //設置請求重試處理 getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler()); /*3.執行 HTTP GET 請求*/ try{ int statusCode = httpClient.executeMethod(getMethod); //判斷訪問的狀態碼 if (statusCode != HttpStatus.SC_OK) System.err.println("Method failed: "+ getMethod.getStatusLine()); filePath=null; /*4.處理 HTTP 響應內容*/ byte[] responseBody = getMethod.getResponseBody();//讀取為字節數組 //根據網頁 url 生成保存時的文件名filePath="temp//"+getFileNameByUrl(url, getMethod.getResponseHeader("Content-Type").getValue()); saveToLocal(responseBody,filePath); } catch (HttpException e) { // 發生致命的異常,可能是協議不對或者返回的內容有問題 System.out.println("Please check your provided http address!"); e.printStackTrace(); } catch (IOException e) { // 發生網絡異常 e.printStackTrace(); } finally { // 釋放連接 getMethod.releaseConnection(); return filePath; //測試的 main 方法 public static void main(String[]args) FileDownLoader downLoader = new FileDownLoader(); downLoader.downloadFile("http://www.twt.edu.cn");} 清單 10 HtmlParserTool.javapackage com.ie;import java.util.HashSet;import java.util.Set;import org.htmlparser.Node;import org.htmlparser.NodeFilter;import org.htmlparser.Parser;import org.htmlparser.filters.NodeClassFilter;import org.htmlparser.filters.OrFilter;import org.htmlparser.tags.LinkTag;import org.htmlparser.util.NodeList;import org.htmlparser.util.ParserException;public class HtmlParserTool { // 獲取一個網站上的鏈接,filter 用來過濾鏈接 public static Set String extracLinks(String url,LinkFilter filter) { Set String links = new HashSet String try { Parser parser = new Parser(url); parser.setEncoding("gb2312"); // 過濾 frame 標簽的 filter,用來提取 frame 標簽里的 src 屬性所表示的鏈接 NodeFilter frameFilter = new NodeFilter() { public boolean accept(Node node) { if (node.getText().startsWith("frame src=")) { return true; } else { return false; // OrFilter 來設置過濾 a 標簽,和 frame 標簽 OrFilter linkFilter = new OrFilter(new NodeClassFilter( LinkTag.class), frameFilter); // 得到所有經過過濾的標簽 NodeList list = parser.extractAllNodesThatMatch(linkFilter); for (int i = 0; i list.size(); i++) { Node tag = list.elementAt(i); if (tag instanceof LinkTag)// a 標簽 LinkTag link = (LinkTag) tag; String linkUrl = link.getLink();// url if(filter.accept(linkUrl)) links.add(linkUrl); } else// frame 標簽 // 提取 frame 里 src 屬性的鏈接如 frame src="test.html"/ String frame = tag.getText(); int start = frame.indexOf("src="); frame = frame.substring(start); int end = frame.indexOf(" "); if (end == -1) end = frame.indexOf(" String frameUrl = frame.substring(5, end - 1); if(filter.accept(frameUrl)) links.add(frameUrl); } catch (ParserException e) { e.printStackTrace(); return links; //測試的 main 方法 public static void main(String[]args)Set String links = HtmlParserTool.extracLinks("http://www.twt.edu.cn",new LinkFilter() //提取以 http://www.twt.edu.cn 開頭的鏈接 public boolean accept(String url) { if(url.startsWith("http://www.twt.edu.cn")) return true; else return false; for(String link : links) System.out.println(link);} 清單11 LinkFilter.javapackage com.ie;public interface LinkFilter { public boolean accept(String url);} 這些代碼中關鍵的部分都在 HttpClient 和 HtmlParser 介紹中說明過了,其他部分也比較容易,請感興趣的讀者自行理解。
更多編程語言

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美高清自拍一区| 亚洲精品视频免费| 欧美精品久久久久久久| 国模精品视频一区二区| 97在线视频精品| 日韩成人在线网站| 国产女人18毛片水18精品| 国产欧美一区二区三区久久| 91精品国产沙发| 国产亚洲精品综合一区91| 亚洲欧美视频在线| 亚洲成年人影院在线| 日韩中文字幕视频| 91在线无精精品一区二区| 成人写真视频福利网| 亚洲91精品在线观看| 97精品国产97久久久久久春色| 亚洲国产成人精品一区二区| 日韩欧美高清在线视频| 国产精品久久久久久久久久三级| 曰本色欧美视频在线| 91在线视频九色| 亚洲欧美日韩视频一区| 日韩亚洲欧美中文高清在线| 日韩专区在线播放| 国产精品成人一区二区三区吃奶| 亚洲欧美综合v| 欧美在线视频观看免费网站| 日av在线播放中文不卡| 国产精品美女久久久久久免费| 亚洲品质视频自拍网| 欧美成人精品在线视频| 国产午夜精品免费一区二区三区| 亚洲美女免费精品视频在线观看| 欧美成人合集magnet| 日韩精品视频在线观看网址| 俺去啦;欧美日韩| 成人国产精品av| 免费99精品国产自在在线| 成人性生交xxxxx网站| 亚洲最大成人在线| 国产精品一区av| 国产精品免费一区二区三区都可以| 国产美女被下药99| 国产区精品视频| 亚洲色图35p| 日本欧美爱爱爱| 国产一区二区日韩| 中文字幕亚洲专区| 国产日韩中文字幕在线| 久久99亚洲精品| 欧美性xxxxx极品娇小| 欧美成人免费播放| 黑人欧美xxxx| 亚洲欧美日韩图片| 亚洲精品二三区| 精品久久久999| 日韩免费视频在线观看| 午夜精品一区二区三区在线视频| 久久精品99国产精品酒店日本| 午夜精品美女自拍福到在线| 91av免费观看91av精品在线| 日韩精品高清在线| 国产日韩视频在线观看| 色妞在线综合亚洲欧美| 亚洲最大av网站| 成人亚洲综合色就1024| 96精品视频在线| 国产成人精品亚洲精品| 欧美激情一区二区三区高清视频| 国产成人综合av| 日韩精品极品在线观看| 欧美激情奇米色| 91精品视频专区| 91社影院在线观看| 亚洲国内高清视频| 国产精品视频网| 九九精品视频在线观看| 日韩av网站大全| 成人a视频在线观看| 怡红院精品视频| 欧美极品欧美精品欧美视频| 韩国19禁主播vip福利视频| 理论片在线不卡免费观看| 日韩视频第一页| 国产精品久久97| 国产一区二区在线播放| 亚洲精品wwww| 国产精品综合网站| 性金发美女69hd大尺寸| 久久久精品国产| 成人网页在线免费观看| 日韩精品在线视频美女| 亚洲二区在线播放视频| 精品久久中文字幕久久av| 欧美另类69精品久久久久9999| 中文字幕久热精品在线视频| 国产精品xxx视频| 国模精品视频一区二区三区| 亚洲成人精品视频| 亚洲欧美日韩精品久久| 国模极品一区二区三区| 欧美一级淫片videoshd| 国产欧美日韩丝袜精品一区| 亚洲在线免费看| 国产精品视频自拍| 日本在线精品视频| 亚洲成人黄色网址| 亚洲国产成人久久| 久久久综合免费视频| 日本欧美中文字幕| 成人福利在线视频| 久久精品国产清自在天天线| 中文字幕欧美日韩va免费视频| 欧美精品一本久久男人的天堂| 国内免费久久久久久久久久久| 欧美激情视频一区| 成人激情黄色网| 欧美多人乱p欧美4p久久| 亚洲一区二区三区四区在线播放| 中文字幕v亚洲ⅴv天堂| 国产亚洲欧美aaaa| 精品福利在线视频| 国产性色av一区二区| 91麻豆国产精品| 91中文字幕在线| 亚洲精品日韩av| 日韩毛片在线看| 亚洲性无码av在线| 亚洲jizzjizz日本少妇| 亚洲高清不卡av| 中文字幕v亚洲ⅴv天堂| 91在线视频导航| 欧美日韩在线免费| 日韩国产中文字幕| 日本电影亚洲天堂| 美女视频黄免费的亚洲男人天堂| 亚洲性av在线| 国产欧美 在线欧美| 国产精品久久久久久久久借妻| 中文字幕久久久| 美女性感视频久久久| 欧美日韩免费在线观看| 欧美孕妇毛茸茸xxxx| 亚洲已满18点击进入在线看片| 欧美激情免费观看| 美女福利视频一区| 欧美成人免费大片| 一区二区三区四区精品| 国产日韩精品一区二区| 久久久国产精品x99av| www日韩中文字幕在线看| 欧美性视频网站| 亚洲免费视频在线观看| 日韩成人xxxx| 精品久久久久久亚洲精品| 欧美夫妻性生活xx| 91精品视频在线| 亚洲精品电影网站| 97欧美精品一区二区三区| 成人久久久久久久| 亚洲第一网站男人都懂| 亚洲区一区二区| 成人av电影天堂|