最近团队在做一个数据集成的系统,需要对一些表单进行爬取,今天就来好好说下一些爬取表单的细节。
其实对于用Htmlunit来爬取一些信息比用Httpclient方便容易,如果是对某些特殊的元素进行爬取,在不知道元素节点的Id或name的时候,需要利用正则表达式来匹配这些,利用匹配出的id或name,在通过HtmlInput根据获取到的id或name来定位相应的元素,可以更加方便的匹配出所有的input信息。
以下算法的流程大致是:
1.根据表单的xml代码用正则表达式匹配出input标签所在的元素块
2.根据匹配出的input元素块匹配出input元素的id
3.根据获取到的input元素的id定位input元素
4.如果获取到的元素为空,则说明此input没有id,需要通过name去定位
5.根据匹配出的input元素块匹配出input元素的name
6.根据获取到的input元素的name定位input元素
7.如果获取到的元素为空,说明元素没有id也没有name,此时无法获取到此元素,放弃此元素
void getInput(HtmlForm forms){
/*用正则提取<input控件*/Matcher matchInput = Pattern.compile("<input[\\s]+.*?>").matcher(forms.asXml());
while(matchInput.find()){//对所有找到的<input>标签进行解析
//如果<input>控件有ID,则使用ID进行定位,否则使用name进行定位
Matcher matchInputId = Pattern.compile("id=\".*?\"").matcher(matchInput.group());
HtmlInput input = null;
if(matchInputId.find()){//说明可以找到控件ID
try {//为什么需要捕获异常,防止有些控件用id无法找到
String[] strs = matchInputId.group().split("\"");
input = page.getHtmlElementById(strs[1]);
if(input!=null){
htmlInputs.add(input);
}
} catch (Exception e) {
}
}
if(input == null ){//说明此时的input标签没有id,需要通过name定位
Matcher matchInputName = Pattern.compile("name=\".*?\"").matcher(matchInput.group());
if(matchInputName.find()){
try {//为什么需要捕获异常,防止有些控件用name无法找到,比如重庆大学的图书馆
input = forms.getInputByName(matchInputName.group().split("\"")[1]);
if(input!=null){
htmlInputs.add(input);
}
} catch (Exception e) {
}
}
}
}
}
//代码中利用java的容器htmlInputs(ArrayList变量)来存储获取到的所以input。