Java JSOUP解析表单字段和标签的表
我试图使用JSOUP解析表中包含字段的表单,以获取字段及其标签。我遇到的问题是找不到标签的任何模式或公共属性。下面是一个HTML页面示例,标签标记为标签1、标签2等,字段标记为字段_1、字段_2等Java JSOUP解析表单字段和标签的表,java,jsoup,Java,Jsoup,我试图使用JSOUP解析表中包含字段的表单,以获取字段及其标签。我遇到的问题是找不到标签的任何模式或公共属性。下面是一个HTML页面示例,标签标记为标签1、标签2等,字段标记为字段_1、字段_2等 <form id="some_form" method="post" action="some_page.do"> <div class="main_div"> <table id="main_table" class="table_class"&
<form id="some_form" method="post" action="some_page.do">
<div class="main_div">
<table id="main_table" class="table_class">
<tr>
<td colspan="10" align="center" class="pad_bottom pad_top">
Label 1:
<input type="text" name="field_1" value="Field 1 value" id="field_1"/>
</td>
</tr>
<tr>
<td colspan="10" align="center">
Label 2:
<span class="radio_class"><input type="radio" name="field_2" value="No" checked="checked" class="radio_field" id="field_2"/> No</span>
<span class="radio_class"><input type="radio" name="field_2" value="Yes" class="radio_field" id="field_2"/> Yes</span><br/>
<span class="extra">Some text to ignore</span>
More text to ignore
</td>
</tr>
<tr>
<td colspan="10" align="center">
<table width="90%">
<tr>
<td class="td_class">
Some text to ignore
</td>
<td class="td_class">
Some text to ignore
</td>
</tr>
<tr>
<td align=3"left" class="another_td_class">
Label 3<br/>
More text for label 3
</td>
<td align="left" class="another_td_class">
<input type="hidden" name="field_3_hidden" value="1" id="field_3"/>
<span class="radio_class"><input type="radio" name="field_3" value="1" id="field_3"/>1</span> 1<br/>
<span class="radio_class"><input type="radio" name="field_3" value="2" checked="checked" onfocus="" id="field_3"/> 2</span> 2<br/>
<br/>
</td>
<tr>
<tr>
</table>
</td>
</tr>
<tr>
<td class="heading" colspan="2" width="50%">Label 4</td>
<td class="heading" width="50%">Label 5</td>
</tr>
<tr>
<td align="center" class="td_class nowrap">
<input type="integer" name="field_4a" maxlength="2" size="2" value="42" class="integer_class" id="field_4"/>
Additional text for label 4
<br/>
<span class="span_class">Text to ignore</span>
</td>
<td class="td_class nowrap">
<input type="radio" name="field_4b" value="A" class="radio_class" id="field_4b"/>A<br/>
<input type="radio" name="field_4b" value="B" checked="checked" class="radio_class" id="field_4b"/>B
<br/>
</td>
<td align="center" class="td_class nowrap">
<input type="radio" name="field_5" value="C" checked="checked" class="radio_class" id="field_5"/>C
<input type="radio" name="field_5" value="D" class="radio_class" id="field_5"/>D
<br/>
</td>
</tr>
</table>
</div>
</form>
标签1:
标签2:
不
是
要忽略的一些文本
更多要忽略的文本
要忽略的一些文本
要忽略的一些文本
标签3
标签3的更多文本
11
2
标签4
标签5
标签4的附加文本
要忽略的文本
A
B
C
D
最接近我的是下面的代码,但是标签经常在不同的地方,有时还有额外的文本,我仍然有问题
Set<MyElement> myElements = new HashSet<MyElement>();
Element mainDiv = page.select("div.main_div").first();
if (mainDiv != null) {
Elements children = mainDiv.children();
Elements tds = children.select("td");
for (Element td : tds) {
Elements inputs = td.select("input");
for (Element input : inputs) {
String field = input.id();
if (field != null && !field.isEmpty()) {
String label = td.text();
MyElement myElement = new MyElement(field, label);
myElements.add(myElement);
}
}
}
}
Set myElements=new HashSet();
Element mainDiv=page.select(“div.main_div”).first();
如果(mainDiv!=null){
Elements children=mainDiv.children();
元素tds=子元素。选择(“td”);
用于(元件td:tds){
元素输入=td。选择(“输入”);
用于(元素输入:输入){
字符串字段=input.id();
if(field!=null&&!field.isEmpty()){
字符串标签=td.text();
MyElement MyElement=新的MyElement(字段、标签);
添加(myElement);
}
}
}
}
如果标签没有任何模式或公共属性,我想我想做的是不可能的,但这是我第一次使用JSOUP,所以我希望有一些我不知道的东西可以让我这样做。我在这里看到一些模式。您说您想要获取字段及其标签。让我们换一种方式来思考这个问题。这是我看到的
你的问题是关于模式,而不是它背后的代码。如果你认为这个答案有效,试着编码它。如果您需要帮助编码,请告诉我。我有一个使用JSOUP的项目,我希望我们愿意编写一个PoC,只要您提供要解析的示例HTML(最好比您已经发布的更多)可能有一种方法。。。这看起来是理解这些标签的一个良好开端 到目前为止,与字段中的标签匹配的粗略系统是:
单元格前面的文本
单元格中的文本
单元格中的文本
中四处走动,找出每个单元格中的文本,并按(行、单元格)存储这些文本,然后从字段返回。其中有一个colspan
值,该值显然计为多个单元格
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class TableParser {
private Map<Integer, Map<Integer, String>> cells = new LinkedHashMap<>();
private void parseTable(Element table) {
int rowNum = 0;
for (Element row : table.select("> tbody > tr")) {
parseRow(rowNum++, row);
}
}
private void parseRow(int rowNum, Element row) {
int columnNum = 0;
for (Element cell : row.select("> td")) {
String colspanText = cell.attr("colspan");
int colspan = 1;
if (StringUtils.isNotBlank(colspanText))
colspan = Integer.parseInt(colspanText);
addCell(rowNum, columnNum, colspan, cell);
parseCell(rowNum, columnNum, cell);
columnNum += colspan;
}
}
private void addCell(int rowNum, int columnNum, int colspan, Element cell) {
Map<Integer, String> rowCells = cells.computeIfAbsent(rowNum,
r -> new LinkedHashMap<>());
for (int i = 0; i < colspan; i++)
rowCells.put(columnNum + i, labelIn(cell));
}
private String labelIn(Element cell) {
return cell.textNodes().get(0).text().trim();
}
private String cellAt(int rowNum, int columnNum) {
Map<Integer, String> rowCells = cells.get(rowNum);
if (rowCells == null)
return null;
return rowCells.get(columnNum);
}
private void parseCell(int rowNum, int columnNum, Element cell) {
// Don't drill down into the nested table yet
if (!cell.select("table").isEmpty())
return;
for (Element input : cell.select("input")) {
String label = labelIn(cell);
if (StringUtils.isBlank(label))
label = cellAt(rowNum, columnNum - 1);
if (StringUtils.isBlank(label))
label = cellAt(rowNum - 1, columnNum);
System.out.println(String.format("%s->%s at (%d,%d)", label,
input.attr("name"), rowNum, columnNum));
}
}
public static void main(String[] args) throws IOException {
Document doc = Jsoup.parse(new java.io.File("/temp/labels.html"),
java.nio.charset.StandardCharsets.UTF_8.name());
for (Element table : doc.select("table")) {
new TableParser().parseTable(table);
}
}
}
1.是的,我关心的是输入2。正确的3。我试图采取这种方法,但遇到了问题。例如,输入ID可能是“status”,而相关标签可能是“What is the status?”因此它们不完全匹配。4.是的,这是正确的,我希望我可以给你从页面上的实际值,但html页面上的信息都是保密的,因此我无法发布实际的html页面或使用的实际值。如果你想用相同格式的lorem ipsum替换保密的htnl,我愿意提供帮助,但是你不能期望任何人在没有精确样本的情况下找到一个模式,事实上,我已经发布的是一个HTML的精确副本,只是更改了机密信息。因此,如果您用lorem lipsum替换标签1和字段_1,这将是唯一的区别。您可以发布基于示例HTML的预期输出吗?仅凭示例很难判断需要选择哪些内容。我更新了上面代码的Java部分,希望能有所帮助。我试图将字段和标签匹配在一起,并将它们放在自定义类中。我想以:[“field_1”、“Label 1”]、[“field_2”、“Label 2”]、[“field_3”、“Label 3”]、[“fie”结尾
Label 1:->field_1 at (0,0)
Label 2:->field_2 at (1,0)
Label 2:->field_2 at (1,0)
Label 4->field_4a at (4,0)
Label 4->field_4b at (4,1)
Label 4->field_4b at (4,1)
Label 5->field_5 at (4,2)
Label 5->field_5 at (4,2)
Label 3->field_3_hidden at (1,1)
Label 3->field_3 at (1,1)
Label 3->field_3 at (1,1)