使用Jsoup爬取uzmanpara.milliyet.com.tr汇率数据空指针异常如何解决
问题原因
- 选择器语法错误:
doc.select("href")写法不符合Jsoup的CSS选择器规则,href是标签的属性不是标签名,该写法无法匹配到任何元素,导致first()返回null,调用attr()触发空指针。如果你的原始需求是匹配所有带href属性的链接,正确选择器应为a[href]。 - 异常处理逻辑漏洞:请求网站的逻辑放在try块内,如果请求抛出IOException,
doc会保持null值,你在try块外直接调用doc.select()也会触发空指针。 - 缺少请求头模拟:目标网站会拦截无浏览器标识的爬虫请求,无UA头可能导致返回内容为空。
正确抓取汇率的实现代码
import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class CurrencyCrawler { public static void main(String[] args) { String url = "https://uzmanpara.milliyet.com.tr/doviz-kurlari/"; try { // 模拟浏览器请求,规避反爬拦截 Document doc = Jsoup.connect(url) .timeout(10000) .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") .get(); // 匹配所有汇率行:找到货币名称所在的td元素,向上获取对应的tr行 Elements currencyRows = doc.select("td.currency").parents("tr"); for (Element row : currencyRows) { // 提取货币名称 String currencyName = row.select("td.currency a").text(); // 提取买入价(第三个td,索引从0开始计数) String buyPrice = row.select("td").get(2).text(); // 提取卖出价(第四个td) String sellPrice = row.select("td").get(3).text(); // 输出结果,也可以自行存入集合或数据库 System.out.printf("货币:%s | 买入价:%s | 卖出价:%s%n", currencyName, buyPrice, sellPrice); // 如果需要获取货币详情页链接,可打开下方注释 // String detailPath = row.select("td.currency a").attr("href"); // String fullDetailUrl = "https://uzmanpara.milliyet.com.tr" + detailPath; } } catch (IOException ex) { Logger.getLogger(CurrencyCrawler.class.getName()).log(Level.SEVERE, "汇率数据请求失败", ex); } } }
补充说明
返回的价格字符串中逗号为土耳其语系的小数点标识,如果需要转换为数值计算,可将逗号替换为小数点后再用BigDecimal解析。
内容的提问来源于stack exchange,提问作者Simurg
相关产品推荐
相关产品推荐

