티스토리 뷰
python의 beautifulsoup이 있다면 java에는 비슷한 jsoup으로 웹 스크래핑을 하고 있습니다
jsoup 1.9.2에서 1.10.2로 업그레이드 하니 한글 파라미터의 경우 중복 인코딩되는 경우가 있음
실제 소스에도 encode 부분이 다음과 같이 변경되었다.
jsoup 1.9.2
private static String encodeUrl(String url) {
if(url == null)
return null;
return url.replaceAll(" ", "%20");
}
jsoup 1.10.2
/**
* Encodes the input URL into a safe ASCII URL string
* @param url unescaped URL
* @return escaped URL
*/
private static String encodeUrl(String url) {
try {
URL u = new URL(url);
return encodeUrl(u).toExternalForm();
} catch (Exception e) {
return url;
}
}
private static URL encodeUrl(URL u) {
try {
// odd way to encode urls, but it works!
final URI uri = new URI(u.getProtocol(), u.getUserInfo(), u.getHost(), u.getPort(), u.getPath(), u.getQuery(), u.getRef());
return new URL(uri.toASCIIString());
} catch (Exception e) {
return u;
}
}
670라인을 보면 아래와 같이 3xx or 201일 때 encodeUrl을 다시 호출함. 기존에도 비슷한 로직이 있었지만 기존 함수는 공백을 %20으로 바꿔주는 기능이어서 문제가 되지 않음.
// redirect if there's a location header (from 3xx, or 201 etc)
if (res.hasHeader(LOCATION) && req.followRedirects()) {
if (status != HTTP_TEMP_REDIR) {
req.method(Method.GET); // always redirect with a get. any data param from original req are dropped.
req.data().clear();
}
String location = res.header(LOCATION);
if (location != null && location.startsWith("http:/") && location.charAt(6) != '/') // fix broken Location: http:/temp/AAG_New/en/index.php
location = location.substring(6);
URL redir = StringUtil.resolve(req.url(), location);
req.url(encodeUrl(redir));
for (Map.Entry<String, String> cookie : res.cookies.entrySet()) { // add response cookies to request (for e.g. login posts)
req.cookie(cookie.getKey(), cookie.getValue());
}
return execute(req, res);
}
파라미터 인코딩없이 쓸 수 있나했더니 이런 문제가.... 우선 1.9.2로 써야겠다.
반응형
댓글