1. 程式人生 > >java中http請求

java中http請求

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近在做爬蟲專案,在瀏覽器下獲取到可以返回json資料的連線,但是使用java.net自帶的請求,請求的只有網頁原始碼,沒有json資料,但是在瀏覽器上可以直接返回json資料。</span>

String urlpath = "http://www.xxxx.xxx/xxx?status=2&xxx=xxxx&xxxx=2&xxxx=120"
URL url = new URL(urlpath);
BufferedReader Rbuff = new BufferedReader(new InputStreamReader(url.openStream()));
使用該方法返回的只有網頁的內容,卻不是想要的結果,難道是根本不能返回。但是另一個同學寫的爬蟲演算法直接呼叫的是apache的第三方的庫,使用上述連線之後,可以正確的返回的json資料,好吧,當時一臉的懵逼。難道是我寫的太簡單了,看來一個java鍾該方法的原始碼,URL().openStream()相當於呼叫URL().openConection().getInputStream()方法,只是整合度更高。上述的區別就是:我的程式在這裡僅僅是對伺服器發出了請求,在瀏覽器中傳送了自己的請求。

查閱了一下瀏覽器傳送http請求的引數:

HTTP協議比較複雜,下面是一個HTT請求的例子:
  
   Host:rss.sina.com.cn
  User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14
  Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
  Accept-Language:zh-cn,zh;q=0.5
  Accept-Encoding:gzip,deflate
  Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
  Keep-Alive:300
  Connection:keep-alive
  Cookie:userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW <-- Cookie
  If-Modified-Since:Sun, 01 Jun 2008 12:05:30 GMT
  Cache-Control:max-age=0

可以看出在瀏覽器中發出請求的時候會將User-Agent這個引數也是就瀏覽器的型別引數一起傳送。進行修改如下:

<span style="white-space:pre">	</span>URL url = new URL(path);
        HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
        urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) ...");
       // urlConnection.setRequestMethod("GET");
        BufferedReader Rbuff = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
新增User-Agent這個引數,可以正確獲取json資料。對於有如下的解釋,對網站的設定不太懂。

對於有些爬蟲來說,這個設定是必要的,譬如有很多網站會對請求頭中的 Referer 進行檢查,以此來防爬或者防盜鏈。又譬如有些網站還會對 User-Agent 進行檢查,根據這個欄位來過濾一些非瀏覽器的請求。如果請求頭設定不對的話,很可能是爬不下正確的資料的。

在這裡講一下http post與get請求的設定:

java中預設的http請求方式是get(這個可以使用urlConnection.getRequestMethod())進行驗證。但是為了更明顯,通常會使用urlConnection.setRequestMethod()對請求方式進行定義。get會將請求引數設定在head中,但是這種方式是明文的,所以當存在使用者名稱與密碼使用get方式傳送的時候,如果被攔截會造成密碼與賬戶的洩露,其實get請求方式並沒有字數的限制,對於get進行字數限制的是瀏覽器head對錶頭有字數的限制。

對於post的請求方式是向伺服器傳送一段資訊,可以使用setDoOutput(true)表示向伺服器傳送資訊。使用如下的方式對輸送的資訊進行轉化成流的形式。

con.setRequestMethod("POST");
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(parameter);
wr.flush();
wr.close();

socket網路程式設計:

其傳輸協議分為udp協議與tcp協議,其中tcp資料的傳輸是需要建立連線的,也就是需要三次握手。而udp資料的傳輸是不要建立連線的,直接將包丟過去,可以從此看出這兩種協議的可靠性,tcp相對於udp更加可靠。

其中:

TCP傳輸資料的過程:

(客戶端與伺服器都可以進行資料的傳送與接收,因此下面有關於客戶端與伺服器可以互換的,不需要太過於爭辯)

Sever(接收):

1.建立一個socket。

2.繫結本地IP地址與埠。

3.進行對埠的監聽。

4.接收來自客戶端的連線,在這裡會有一個執行緒堵塞的過程,因此需要開闢新執行緒。

5.接收資料流(資料的來源一般就是對socket直接流的擷取)。

6.讀取資料流並進行字元轉換。

7.關閉監聽與socket

client

1.建立一個socket。

2.繫結本地ip與埠。

3.連線另一端的IP地址與埠。

4.傳輸資料

5.關閉埠與socket

UPD資料傳輸的過程

Sever:

1.建立一個socket。

2.繫結本地IP地址與埠。

3.繫結另一端的IP地址與埠。

4.迴圈讀取資料

5關閉socket

client:

1.建立一個socket。

2.繫結本地IP地址與埠。

3.繫結另一端的IP地址與埠。

4.傳送資料

5關閉socket