Theory
gì tôi sẽ làm là tạo ra một chương trình nhỏ mà có thể tự động gửi bất kỳ dữ liệu mẫu để bất cứ nơi nào và trở lại với kết quả. Điều này rất dễ thực hiện trong Java với HTTPUnit. Tác vụ như sau:
- Kết nối với máy chủ web.
- Phân tích trang.
- Nhận biểu mẫu đầu tiên trên trang.
- Điền vào dữ liệu biểu mẫu.
- Gửi biểu mẫu.
- Đọc (và phân tích cú pháp) kết quả.
Giải pháp bạn chọn sẽ phụ thuộc vào nhiều yếu tố, bao gồm:
- dù bạn cần phải bắt chước Javascript
- Những gì bạn cần làm với các dữ liệu sau đó
- Những ngôn ngữ với bạn thành thạo
- Tốc độ ứng dụng (cho một truy vấn hoặc 100.000?)
- Ứng dụng cần phải hoạt động bao lâu
- Đây có phải là một sự cố, hoặc nó sẽ phải được duy trì?
Ví dụ, bạn có thể thử các ứng dụng sau đây để gửi dữ liệu cho bạn:
Sau đó grep (awk, hoặc sed) (các) trang web kết quả.
Một mẹo khác khi cạo màn hình là tải xuống tệp HTML mẫu và phân tích cú pháp thủ công trong vi (hoặc VIM) theo cách thủ công. Lưu các tổ hợp phím vào một tệp và sau đó bất cứ khi nào bạn chạy truy vấn, hãy áp dụng các lần nhấn phím đó vào (các) trang web kết quả để trích xuất dữ liệu. Giải pháp này không thể duy trì, cũng không đáng tin cậy 100% (nhưng hiếm khi có màn hình cạo từ trang web). Nó hoạt động và nhanh.
Ví dụ
Một lớp Java bán chung để nộp tờ trang web (đặc biệt là đối phó với đăng nhập vào một trang web) là dưới đây, với hy vọng rằng nó có thể có ích. Không sử dụng nó cho cái ác.
import java.io.FileInputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.SubmitButton;
import com.meterware.httpunit.WebClient;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
public class FormElements extends Properties
{
private static final String FORM_URL = "form.url";
private static final String FORM_ACTION = "form.action";
/** These are properly provided property parameters. */
private static final String FORM_PARAM = "form.param.";
/** These are property parameters that are required; must have values. */
private static final String FORM_REQUIRED = "form.required.";
private Hashtable fields = new Hashtable(10);
private WebConversation webConversation;
public FormElements()
{
}
/**
* Retrieves the HTML page, populates the form data, then sends the
* information to the server.
*/
public void run()
throws Exception
{
WebResponse response = receive();
WebForm form = getWebForm(response);
populate(form);
form.submit();
}
protected WebResponse receive()
throws Exception
{
WebConversation webConversation = getWebConversation();
GetMethodWebRequest request = getGetMethodWebRequest();
// Fake the User-Agent so the site thinks that encryption is supported.
//
request.setHeaderField("User-Agent",
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv\\:1.7.3) Gecko/20040913");
return webConversation.getResponse(request);
}
protected void populate(WebForm form)
throws Exception
{
// First set all the .param variables.
//
setParamVariables(form);
// Next, set the required variables.
//
setRequiredVariables(form);
}
protected void setParamVariables(WebForm form)
throws Exception
{
for(Enumeration e = propertyNames(); e.hasMoreElements();)
{
String property = (String)(e.nextElement());
if(property.startsWith(FORM_PARAM))
{
String fieldName = getProperty(property);
String propertyName = property.substring(FORM_PARAM.length());
String fieldValue = getField(propertyName);
// Skip blank fields (most likely, this is a blank last name, which
// means the form wants a full name).
//
if("".equals(fieldName))
continue;
// If this is the first name, and the last name parameter is blank,
// then append the last name field to the first name field.
//
if("first_name".equals(propertyName) &&
"".equals(getProperty(FORM_PARAM + "last_name")))
fieldValue += " " + getField("last_name");
showSet(fieldName, fieldValue);
form.setParameter(fieldName, fieldValue);
}
}
}
protected void setRequiredVariables(WebForm form)
throws Exception
{
for(Enumeration e = propertyNames(); e.hasMoreElements();)
{
String property = (String)(e.nextElement());
if(property.startsWith(FORM_REQUIRED))
{
String fieldValue = getProperty(property);
String fieldName = property.substring(FORM_REQUIRED.length());
// If the field starts with a ~, then copy the field.
//
if(fieldValue.startsWith("~"))
{
String copyProp = fieldValue.substring(1, fieldValue.length());
copyProp = getProperty(copyProp);
// Since the parameters have been copied into the form, we can
// eke out the duplicate values.
//
fieldValue = form.getParameterValue(copyProp);
}
showSet(fieldName, fieldValue);
form.setParameter(fieldName, fieldValue);
}
}
}
private void showSet(String fieldName, String fieldValue)
{
System.out.print("<p class='setting'>");
System.out.print(fieldName);
System.out.print(" = ");
System.out.print(fieldValue);
System.out.println("</p>");
}
private WebForm getWebForm(WebResponse response)
throws Exception
{
WebForm[] forms = response.getForms();
String action = getProperty(FORM_ACTION);
// Not supposed to break out of a for-loop, but it makes the code easy ...
//
for(int i = forms.length - 1; i >= 0; i--)
if(forms[ i ].getAction().equalsIgnoreCase(action))
return forms[ i ];
// Sadly, no form was found.
//
throw new Exception();
}
private GetMethodWebRequest getGetMethodWebRequest()
{
return new GetMethodWebRequest(getProperty(FORM_URL));
}
private WebConversation getWebConversation()
{
if(this.webConversation == null)
this.webConversation = new WebConversation();
return this.webConversation;
}
public void setField(String field, String value)
{
Hashtable fields = getFields();
fields.put(field, value);
}
private String getField(String field)
{
Hashtable<String, String> fields = getFields();
String result = fields.get(field);
return result == null ? "" : result;
}
private Hashtable getFields()
{
return this.fields;
}
public static void main(String args[])
throws Exception
{
FormElements formElements = new FormElements();
formElements.setField("first_name", args[1]);
formElements.setField("last_name", args[2]);
formElements.setField("email", args[3]);
formElements.setField("comments", args[4]);
FileInputStream fis = new FileInputStream(args[0]);
formElements.load(fis);
fis.close();
formElements.run();
}
}
Một tập tin ví dụ thuộc tính sẽ như thế nào:
$ cat com.mellon.properties
form.url=https://www.mellon.com/contact/index.cfm
form.action=index.cfm
form.param.first_name=name
form.param.last_name=
form.param.email=emailhome
form.param.comments=comments
# Submit Button
#form.submit=submit
# Required Fields
#
form.required.to=zzwebmaster
form.required.phone=555-555-1212
form.required.besttime=5 to 7pm
Run nó tương tự như sau (thay thế đường dẫn đến HttpUnit và lớp FormElements với $ CLASSPATH):
java -cp $CLASSPATH FormElements com.mellon.properties "John" "Doe" "[email protected]" "To whom it may concern ..."
Tính hợp pháp
Câu trả lời khác r đã đề cập rằng nó có thể vi phạm điều khoản sử dụng. Kiểm tra điều đó trước tiên, trước khi bạn dành bất kỳ lúc nào để xem xét giải pháp kỹ thuật. Lời khuyên cực kỳ tốt.
Ồ, cảm ơn vì điều này. Đã đến lúc đọc nó: D – kgrad
Bạn được chào đón; nó đang ngồi xung quanh thu thập bụi kỹ thuật số. –