⑴ java爬蟲一段話里的部分字元亂碼解決
1. 網路爬蟲亂碼的原因。
源網頁的編碼與抓取後的編碼轉換不一致。如果源網頁是gbk編碼的位元組流,程序在我們抓取後直接用utf-8編碼輸出到存儲文件,這必然會造成亂碼,即當源網頁編碼與程序抓取後直接處理編碼一致時,就不會出現亂碼,然後統一字元編碼後也就不會出現亂碼。注意區分源網路代碼A,程序B直接使用的代碼,統一轉換字元的代碼C。
2. 是網頁的伺服器端代碼。
B.捕獲的數據原本是位元組數組,由A編碼,只有B=A才能保證不會出現亂碼;否則,當字元集不兼容時,就會出現亂碼字元。這一步常用於測試。
c、統一轉碼是指在獲得網頁的原始編碼A後進行統一編碼,主要是將每個網頁的數據統一成一種編碼,往往首選字元集較大的utf-8。
每個網頁都有自己的代碼,比如gbk,utf-8,iso8859-1,日本jp系統代碼,西歐,俄語等等。爬行時,所有類型的代碼都將被擴展。有的爬蟲只是簡單的識別網頁,然後統一編碼,有的則直接按照utf-8統一處理,不需要判斷源網頁,顯然會造成亂碼。
3. 亂碼的解決方案。
根據原因找到解決辦法很簡單。
1) 確定源網頁的代碼a。
代碼a通常位於網頁的三個位置,即httpheader的內容、網頁的元字元集和網頁標題中的文檔定義。獲取源網頁代碼時,依次判斷這三部分數據,從頭到尾優先順序相同。
理論上這是對的,但是國內有些網站不符合標准。比如寫出來的gbk其實是utf-8,有的寫出來是utf-8,其實是gbk。當然這是幾個網站,但是確實存在。因此,在確定網頁編碼時,應該對這種特殊情況給予特殊處理,如中文檢查、默認編碼等策略。
在另一種情況下,如果以上三種都沒有編碼信息,一般使用第三方的網頁編碼智能識別工具,如cpdetector。原理是通過統計位元組數組的特性來計算實際編碼,有一定的准確率,但是我發現在實踐中准確率還是很有限的。
但是綜合以上三種編碼確認方法後,中文亂碼的問題幾乎可以完全解決。在我的基於nutch1.6的網路爬蟲系統中,經過統計,編碼准確率可以達到99.99%,這也證明了上述方法和策略的可行性。
2) 程序通過代碼b還原源網頁數據。
顯然,這里的B應該等於a,在java中,如果源網頁的位元組數組是source_byte_array,就會轉換成stringstr=newstring(source_byte_array,B)。即這些位元組數組對應的字元被正確編碼顯示在內存中,此時列印結果正常。此步驟通常用於調試或控制台輸出測試。
3) 統一轉碼。
網路爬蟲系統中有很多數據源。如果無法使用數據,它將被轉換為其原始數據,如果這樣做是浪費的。所以一般爬蟲系統要對抓取的結果進行統一編碼,做到一致,使用方便。此時,在(2)的基礎上,可以進行統一的編碼轉換,在java中的實現如下。
源網頁的位元組數組是source_byte_array。
轉換為普通字元串:stringnormal_source_str=newstring(source_byte_array,c)。這時候可以直接用javaapi存儲,但是字元串往往不直接寫。因為一般爬蟲存儲是將多個源網頁存儲在一個文件中,所以要記錄位元組偏移量,所以下一步。 再將得到的str轉換為統一的編碼C格式的位元組數組,則byte[] new_byte_array=normal_source_str.getBytes(C)即可,此時即可用java io api將數組寫入文件,並記錄相應的位元組數組偏移量等,待真正使用時,直接io讀取即可。
爬蟲過程不僅會存在亂碼問題,還會存在網站爬取涉及法律、IP受限,爬取行為受限等等問題,這個時候就需要不斷去解決這些問題。
⑵ java文件亂碼,不是中文亂碼,是整個都亂碼
我們在eclipse中打開java項目,發現中文都是亂碼。
首先我們可以打開工具菜單「Project」--「Properties」。
⑶ java程序執行中文亂碼如何解決
看你編譯沒問題,運行時報亂碼錯誤。說明是代碼的編碼跟DOS系統的編碼不一致。
DOS系統是ASCII碼,你看一下你代碼的編碼是什麼,應該不是ASCII碼,你把你的代碼編碼轉換成ASCII碼試試先,不行再轉成UTF-8試試,這樣應該就解決了(如果是編碼不一致的問題的話)
⑷ javaweb怎麼處理中文亂碼問題
中文亂碼問題真的是一個很棘手的問題,特別是從前台傳到後台之後,都不知道問題出在哪裡了。現在分享解決javaWEB中前後台中文亂碼問題的3種方法。
方法一:
tomcat的自帶編碼是ISO-8859-1的格式,是不兼容中文的編碼的。所以我們從後台接收的時候要注意。
採用相同的格式去接收(ISO-8859-1),然後用能解析的編碼(utf-8)去轉換。這樣我們就能得到能兼容中文的格式了。這樣處理之後發往前台。注意:發往前台的時候也需要設置一下
resp.setContentType("text/html;charset=utf-8");//設置頁面的字元編碼,解決界面顯示中文亂碼的問題
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//因為tomcat自帶編碼是ISO-8859-1格式
//解決亂碼方法之一
<span style="white-space:pre"> </span>String name=req.getParameter("username");
<span style="white-space:pre"> </span>String pwd=req.getParameter("pwd");
<span style="white-space:pre"> </span>byte[] b=name.getBytes("ISO-8859-1");//用tomcat的格式(iso-8859-1)方式去讀。
<span style="white-space:pre"> </span>String str=new String(b,"utf-8");//採用utf-8去接string
<span style="white-space:pre"> </span>resp.setContentType("text/html;charset=utf-8");//設置頁面的字元編碼<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>PrintWriter pw =resp.getWriter();
<span style="white-space:pre"> </span>String str1="<html><body><font size='5px' color='red'>username:"+name+"pwd:"+pwd+"</font></body></html>";
<span style="white-space:pre"> </span>pw.print(str1);
PrintWriter pw =resp.getWriter();
String str1="<html><body><font size='5px' color='red'>username:"+name+"pwd:"+pwd+"</font></body></html>";
pw.print(str1);
方法二:
由於方法一比較繁瑣,採用用了簡單的設置。只需要簡單的一句就可以搞定
req.setCharacterEncoding("utf-8");//必須寫在第一位,因為採用這種方式去讀取數據,否則數據會出錯。
這樣就不用像之前的那樣繁瑣的設置了
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//因為tomcat自帶編碼是ISO-8859-1格式
//解決亂碼二《法一比較繁瑣》
req.setCharacterEncoding("utf-8");//必須寫在第一位,因為採用這種方式去讀取數據,否
則數據會出錯。
//設置這樣方式去讀。這樣中文就能夠讀取出來了,但是需要注意。表單的發送方式必須是<span style="color:#ff0000;"> method='post'</span>
resp.setContentType("text/html;charset=utf-8");//設置傳過去的頁面顯示的編碼
String name=req.getParameter("username");
String pwd=req.getParameter("pwd");
PrintWriter pw =resp.getWriter();
String str1="<html><body><font size='5px' color='red'>username:"+name+"pwd:"+pwd+"</font></body></html>";
pw.print(str1);
方法三:
這是在法二的基礎上修改的。雖然我們能修改編碼格式去讀,但是考慮到用戶肯定不會修改,所以我們需要採用比較通用的辦法,讓用戶修改配置文件。也就是web.xml文件
需要修改web.xml裡面的內容,就是說,字元編碼從xml接收過來。需要在xml文件中配置參數。
代碼如下:
<servlet>
<servlet-name>Encodeing</servlet-name>
<servlet-class>cn.hncu.com.encode.Encodeing</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>utf-8</param-value>//這裡面的內容可供用戶自己填寫(必須是編碼格式)
</init-param>
</servlet>
我們知道前台和後台進行交換必須經過web.xml配置
我們需要獲取web.xml的設置的參數
public void init(ServletConfig config) throws ServletException {
charset=config.getInitParameter("charset");//獲得初始化參數。當然charset需要設置為全局變數。後面的service函數需要設置req.setCharacterEncoding(charset);
}
req.setCharacterEncoding(charset);
resp.setContentType("text/html;charset=utf-8");
String name=req.getParameter("username");
String pwd=req.getParameter("pwd");
PrintWriter pw =resp.getWriter();
String str1="<html><body><font size='5px' color='red'>username:"+name+"pwd:"+pwd+"</font></body></html>";
pw.print(str1);
⑸ java中文亂碼,能說下string.getBytes()和new String()轉碼是,具體點。
1、Java中,【String.getBytes(String decode)】的方法,會根據指定的decode,編碼返回某字元串在該編碼下的byte數組表示,例如:
byte[] b_gbk = "中".getBytes("GBK");
byte[] b_utf8 = "中".getBytes("UTF-8");
byte[] b_iso88591 = "中".getBytes("ISO8859-1")
上面三行代碼表示:分別返回「中」這個漢字在GBK、UTF-8和ISO8859-1編碼下的byte數組表示,此時b_gbk的長度為2,b_utf8的長度為3,b_iso88591的長度為1。
2、而通過【new String(byte[], decode)】的方式來還原這個「中」字時,實際是使用decode指定的編碼來將byte[ ]解析成字元串,例如:
String s_gbk = new String(b_gbk,"GBK");
String s_utf8 = new String(b_utf8,"UTF-8");
String s_iso88591 = new String(b_iso88591,"ISO8859-1");
s_gbk和s_utf8都是「中」,而只有s_iso88591是一個不認識 的字元,因為ISO8859-1編碼的編碼表中,根本就沒有包含漢字字元,當然也就無法通過"中".getBytes("ISO8859-1")。
因此,通過【String.getBytes(String decode)】方法來得到byte[ ]時,要確定decode的編碼表中確實存在String表示的碼值,這樣得到的byte[ ]數組才能正確被還原。
(5)java亂碼轉換擴展閱讀
java中文編碼避免亂碼
1、為了讓中文字元適應某些特殊要求(如http header頭要求其內容必須為iso8859-1編碼),可能會通過將中文字元按照位元組方式來編碼的情況,比如:
String s_iso88591 = new String("中".getBytes("UTF-8"),"ISO8859-1")
2、上述例子中的s_iso8859-1字元串實際是三個在 ISO8859-1中的字元,在將這些字元傳遞到目的地後,目的地程序再通過相反的方式:
String s_utf8 = new String(s_iso88591.getBytes("ISO8859-1"),"UTF-8")
來得到正確的中文漢字。這樣就既保證了遵守協 議規定、也支持中文。
3、String.getBytes(String decode)方法會根據指定的decode編碼返回某字元串在該編碼下的byte數組表示這里是encode ,not decode,從字元串到位元組數組是編碼的過程,從位元組數組到字元串(即 new String(byte[] , charsetname))才是解碼的過程。
⑹ 淺談如何解決Java/JSP中文亂碼問題
原因主要有兩方面,Java和JSP文件本身編譯時產生的亂碼問題和Java程序於其他媒介交互產生的亂碼問題。首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基於位元組流的,如果Java和JSP編譯成class文件過程中,使用的編碼方式與源文件的編碼不一致,就會出現亂碼。基於這種亂碼,建議在Java文件中盡量不要寫中文(注釋部分不參與編譯,寫中文沒關系),如果必須寫的話,盡量手動帶參數-ecoding GBK或-ecoding gb2312編譯;對於JSP,在文件頭加上或基本上就能解決這類亂碼問題。本文要重點討論的是第二類亂碼,即Java程序與其他存儲媒介交互時產生的亂碼。很多存儲媒介,如資料庫,文件,流等的存儲方式都是基於位元組流的,Java程序與這些媒介交互時就會發生字元(char)與位元組(byte)之間的轉換,具體情況如下:從頁面form提交數據到java程序 byte->char從java程序到頁面顯示 char?>byte從資料庫到java程序 byte?>char從java程序到資料庫 char?>byte從文件到java程序 byte->char從java程序到文件 char->byte從流到java程序 byte->char從java程序到流 char->byte如果在以上轉換過程中使用的編碼方式與位元組原有的編碼不一致,很可能就會出現亂碼。二、Java/JSP中文亂碼的解決方法前面已經提到了Java程序與其他媒介交互時字元和位元組的轉換過程,如果這些轉換過程中容易產生亂碼。解決這些亂碼問題的關鍵在於確保轉換時使用的編碼方式與位元組原有的編碼方式保持一致,下面分別論述(Java或JSP自身產生的亂碼請參看第一部分)。1、JSP與頁面參數之間的亂碼JSP獲取頁面參數時一般採用系統默認的編碼方式,如果頁面參數的編碼類型和系統默認的編碼類型不一致,很可能就會出現亂碼。解決這類亂碼問題的基本方法是在頁面獲取參數之前,強制指定request獲取參數的編碼方式:request.setCharacterEncoding("GBK")或 request.setCharacterEncoding("gb2312")。如果在JSP將變數輸出到頁面時出現了亂碼,可以通過設置 response.setContentType("text/html;charset=GBK")或 response.setContentType("text/html;charset=gb2312")解決。如果不想在每個文件里都寫這樣兩句話,更簡潔的辦法是使用Servlet規范中的過慮器指定編碼,過濾器的在web.xml中的典型配置和主要代碼如下:web.xml: CharacterEncodingFilter net.vschool.web.CharacterEncodingFilter encodingGBK CharacterEncodingFilter /* CharacterEncodingFilter.java: public class CharacterEncodingFilter implements Filter { protected String encoding = null; public void init(FilterConfig filterConfig) throws ServletException { this.encoding = filterConfig.getInitParameter("encoding"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(encoding); response.setContentType("text/html;charset="+encoding); chain.doFilter(request, response); } } 2、Java與資料庫之間的亂碼大部分資料庫都支持以unicode編碼方式,所以解決Java與資料庫之間的亂碼問題比較明智的方式是直接使用unicode編碼與資料庫交互。很多資料庫驅動自動支持unicode,如Microsoft的SQLServer驅動。其他大部分資料庫驅動,可以在驅動的url參數中指定,如如mm的mysql驅動:jdbc:mysql://localhost /WEBCLDB?useUnicode=true&characterEncoding=GBK。3、Java與文件/流之間的亂碼Java讀寫文件最常用的類是 FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream 和FileOutputStream是基於位元組流的,常用於讀寫二進制文件。讀寫字元文件建議使用基於字元的FileReader和 FileWriter,省去了位元組與字元之間的轉換。但這兩個類的構造函數默認使用系統的編碼方式,如果文件內容與系統編碼方式不一致,可能會出現亂碼。在這種情況下,建議使用FileReader和FileWriter的父類:InputStreamReader/OutputStreamWriter,它們也是基於字元的,但在構造函數中可以指定編碼類型:InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。4、其他上面提到的方法應該能解決大部分亂碼問題,如果在其他地方還出現亂碼,可能需要手動修改代碼。解決Java亂碼問題的關鍵在於在位元組與字元的轉換過程中,你必須知道原來位元組或轉換後的位元組的編碼方式,轉換時採用的編碼必須與這個編碼方式保持一致。
⑺ java中字元亂碼轉化的問題
如果B接受編碼方式也不能更改為和A一致,那麼舉個例子
A GBK,B UTF-8
B獲取的內容亂碼,
String s=request.getParameter("欄位名");
這里s會亂碼,可以做如下轉換
byte[] bytes=s.getBytes(" B當前的編碼格式");
String s=new String(bytes,"A的編碼方式");
這個時候s就正常了
⑻ java中文亂碼問題
亂碼問題也是我一直覺得比較蛋疼的問題,下面是我在網上看到的,樓主可以參考一下
一、Java中文問題的由來
Java的內核和class文件是基於unicode的,這使Java程序具有良好的跨平台性,但也帶來了一些中文亂碼問題的麻煩。原因主要有兩方面,Java和JSP文件本身編譯時產生的亂碼問題和Java程序於其他媒介交互產生的亂碼問題。
首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基於位元組流的,如果Java和JSP編譯成class文件過程中,使用的編碼方式與源文件的編碼不一致,就會出現亂碼。基於這種亂碼,建議在Java文件中盡量不要寫中文(注釋部分不參與編譯,寫中文沒關系),如果必須寫的話,盡量手動帶參數-ecoding GBK或-ecoding gb2312編譯;對於JSP,在文件頭加上或基本上就能解決這類亂碼問題。
本文要重點討論的是第二類亂碼,即Java程序與其他存儲媒介交互時產生的亂碼。很多存儲媒介,如資料庫,文件,流等的存儲方式都是基於位元組流的,Java程序與這些媒介交互時就會發生字元(char)與位元組(byte)之間的轉換,具體情況如下:
從頁面form提交數據到java程序 byte->char
從java程序到頁面顯示 char?>byte
從資料庫到java程序 byte?>char
從java程序到資料庫 char?>byte
從文件到java程序 byte->char
從java程序到文件 char->byte
從流到java程序 byte->char
從java程序到流 char->byte
如果在以上轉換過程中使用的編碼方式與位元組原有的編碼不一致,很可能就會出現亂碼。
二、解決方法
前面已經提到了Java程序與其他媒介交互時字元和位元組的轉換過程,如果這些轉換過程中容易產生亂碼。解決這些亂碼問題的關鍵在於確保轉換時使用的編碼方式與位元組原有的編碼方式保持一致,下面分別論述(Java或JSP自身產生的亂碼請參看第一部分)。
1、JSP與頁面參數之間的亂碼
JSP獲取頁面參數時一般採用系統默認的編碼方式,如果頁面參數的編碼類型和系統默認的編碼類型不一致,很可能就會出現亂碼。解決這類亂碼問題的基本方法是在頁面獲取參數之前,強制指定request獲取參數的編碼方式:request.setCharacterEncoding("GBK")或request.setCharacterEncoding("gb2312")。
如果在JSP將變數輸出到頁面時出現了亂碼,可以通過設置response.setContentType("text/html;charset=GBK")或response.setContentType("text/html;charset=gb2312")解決。
如果不想在每個文件里都寫這樣兩句話,更簡潔的辦法是使用Servlet規范中的過慮器指定編碼,過濾器的在web.xml中的典型配置和主要代碼如下:
web.xml:
CharacterEncodingFilter
net.vschool.web.CharacterEncodingFilter
encodingGBK
CharacterEncodingFilter
/*
CharacterEncodingFilter.java:
public class CharacterEncodingFilter implements Filter
{
protected String encoding = null;
public void init(FilterConfig filterConfig) throws ServletException
{
this.encoding = filterConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
chain.doFilter(request, response);
}
}
2、Java與資料庫之間的亂碼
大部分資料庫都支持以unicode編碼方式,所以解決Java與資料庫之間的亂碼問題比較明智的方式是直接使用unicode編碼與資料庫交互。很多資料庫驅動自動支持unicode,如Microsoft的SQLServer驅動。其他大部分資料庫驅動,可以在驅動的url參數中指定,如如mm的mysql驅動:jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK。
3、Java與文件/流之間的亂碼
Java讀寫文件最常用的類是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基於位元組流的,常用於讀寫二進制文件。讀寫字元文件建議使用基於字元的FileReader和FileWriter,省去了位元組與字元之間的轉換。但這兩個類的構造函數默認使用系統的編碼方式,如果文件內容與系統編碼方式不一致,可能會出現亂碼。在這種情況下,建議使用FileReader和FileWriter的父類:InputStreamReader/OutputStreamWriter,它們也是基於字元的,但在構造函數中可以指定編碼類型:InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。
4、其他
上面提到的方法應該能解決大部分亂碼問題,如果在其他地方還出現亂碼,可能需要手動修改代碼。解決Java亂碼問題的關鍵在於在位元組與字元的轉換過程中,你必須知道原來位元組或轉換後的位元組的編碼方式,轉換時採用的編碼必須與這個編碼方式保持一致。我們以前使用Resin伺服器,使用smartUpload組件上傳文件,上傳文件同時傳遞的中文參數獲取沒有亂碼問題。當在Linux中把Resin設置成服務後,上傳文件同時的中文參數獲取出現了亂碼。這個問題困擾了我們很久,後來我們分析smartUpload組件的源文件,因為文件上傳採用的是位元組流的方式,裡麵包含的參數名稱和值也是位元組流的方式傳遞的。smartUpload組件讀取位元組流後再將參數名稱和值從位元組流中解析出來,問題就出現在smartUpload將位元組流轉換成字元串時採用了系統默認的編碼,而將Resin設置成服務後,系統默認的編碼可能發生了改變,因此出現了亂碼。後來,我們更改了smartUpload的源文件,增加了一個屬性charset和setCharset(String)方法,將upload()方法中提取參數語句:
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1 );
改成了
String value = new String(m_binArray, m_startData, (m_endData - m_startData) + 1, charset );
出處:http://www.enet.com.cn/article/2008/0229/A20080229170410.shtml
⑼ Java編碼時輸入漢字出現亂碼解決方法
java文件讀取的時候有中文就很出現亂碼,通常獲取到的文件中通常都是「iso8859-1」格式,需要轉換為「UTF-8」格式。
如:String str = new String(str.getByte("iso8859-1"),"UTF-8");進行下強制轉換後在進行讀取即可。
備註:通常格式有GBK、UTf-8、iso8859-1、GB2312,如果上面的強制轉換不成功,依次進行這些格式的嘗試,肯定是可以解決問題的。
⑽ java中文亂碼怎麼轉換為漢字
我遇到過和你一樣的錯誤,
在你編寫String gb = new String(「資料庫查處來的中文」.getBytes("ISO-8859-1"),"UTF-8");這句話的時候請注意一下「資料庫查處來的中文」必須是ISO-8859-1編碼,否則轉換失敗。
另外光資料庫是UTF-8編碼是不行的,請確定一下資料庫建表的時候是否設置成UTF-8編碼。
希望我的回答能夠幫助你,謝謝