2009-07-17 2 views
7

공개 API를 사용하지 않고 Google과 같은 사이트의 텍스트 상자에 문자열을 입력 한 다음 양식을 제출하고 결과를 얻는 프로그램을 만들고 싶습니다. 이것이 가능한가? 결과를 얻으려면 내가 생각하는 HTML 스크래핑을 사용해야하지만 텍스트 필드에 데이터를 입력하고 양식을 제출하려면 어떻게해야합니까? 공개 API를 사용해야합니까? 이런 것이 가능한 것 아닌가? 쿼리 문자열/매개 변수를 찾아야합니까?API를 사용하지 않고 프로그래밍 방식으로 검색을 수행하려면 어떻게해야합니까?

감사합니다.

답변

4

이론

내가 무엇을 할 것은 자동으로 어떤 장소에 어떤 형태의 데이터를 입력하고 다시 결과에 올 수있는 작은 프로그램을 만드는 것입니다. Java에서 HTTPUnit으로 쉽게 할 수 있습니다. 작업은 다음과 같이 진행됩니다.

  • 웹 서버에 연결하십시오.
  • 페이지를 구문 분석하십시오.
  • 페이지에서 첫 번째 양식을 가져옵니다.
  • 양식 데이터를 입력하십시오.
  • 양식을 제출하십시오.
  • 결과를 읽고 구문 분석하십시오.

당신을 포함하여 다양한 요인에 따라 달라집니다 선택 솔루션 :

  • 당신은 당신이 나중에 데이터를
  • 어떤 언어를 할 필요가 무엇 자바 스크립트
  • 를 에뮬레이션해야하는지 여부 당신은 능숙합니다.
  • 응용 프로그램 속도 (하나의 쿼리 또는 100,000에 대해?)
  • 응용 프로그램이 작동해야하는 시간
  • 일시 중지되었거나 유지 관리해야합니까?

예를 들어, 당신은 당신을 위해 데이터를 전송하기 위해 다음과 같은 응용 프로그램을 시도 할 수 :

다음 grep은 (AWK, 또는 나오지도) 결과 웹 페이지 (들).

화면 스크래핑의 또 다른 트릭은 샘플 HTML 파일을 다운로드하고 vi (또는 VIM)에서 수동으로 구문 분석하는 것입니다. 키 입력을 파일에 저장 한 다음 쿼리를 실행할 때마다 해당 키 입력을 결과 웹 페이지에 적용하여 데이터를 추출하십시오. 이 솔루션은 유지 보수가 불가능하거나 100 % 신뢰성이 없습니다 (그러나 웹 사이트에서 화면 스크래핑이 거의없는 경우). 그것은 효과적이고 빠르다.

가 유용 할 수 있다는 희망, (특히 웹 사이트에 로그인 처리) 아래 인 웹 사이트 양식을 제출 반 일반적인 자바 클래스입니다. 그것을 악에 사용하지 마십시오.

java -cp $CLASSPATH FormElements com.mellon.properties "John" "Doe" "[email protected]" "To whom it may concern ..." 

:

$ 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 

실행이 유사한 (HttpUnit은 경로를 대체하고 $ CLASSPATH에 대한 FormElements 클래스) 다음에 :

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(); 
    } 
} 

예 특성 파일과 같을 것이다 법률

다른 답변 r은 이용 약관을 위반할 수 있다고 언급했습니다. 기술 솔루션을 조사하기 전에 먼저 확인하십시오. 매우 좋은 조언.

+0

와우, 고맙습니다. 그것을 읽을 시간 : D – kgrad

+0

당신을 진심으로 환영합니다; 그것은 디지털 먼지를 모으기 위해 앉아있었습니다. –

2

대부분의 경우 간단한 HTTP POST 요청 만 보낼 수 있습니다.

웹이 어떻게 작동하는지 이해하려면 Fiddler으로 놀아 보시기 바랍니다.

거의 모든 프로그래밍 언어와 프레임 워크에는 원시 요청을 보내는 방법이 있습니다.

그리고 언제든지 Internet Explorer ActiveX 컨트롤을 프로그래밍 할 수 있습니다. 나는 많은 프로그래밍 언어가 그것을 지원한다고 믿는다.

1

음, 여기에 구글 페이지에서 HTML의 :

<form action="/search" name=f><table cellpadding=0 cellspacing=0><tr valign=top> 
<td width=25%>&nbsp;</td><td align=center nowrap> 
<input name=hl type=hidden value=en> 
<input type=hidden name=ie value="ISO-8859-1"> 
<input autocomplete="off" maxlength=2048 name=q size=55 title="Google Search" value=""> 
<br> 
<input name=btnG type=submit value="Google Search"> 
<input name=btnI type=submit value="I'm Feeling Lucky"> 
</td><td nowrap width=25% align=left> 
<font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en> 
Advanced Search</a><br>&nbsp;&nbsp; 
<a href=/preferences?hl=en>Preferences</a><br>&nbsp;&nbsp; 
<a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table> 
</form> 

당신은 단지 그것을 시도하고 다시 무엇을 얻을 참조 좋아하는 프로그래밍 언어에서 HTTP 요청을하는 방법을 알고있는 경우

. 예를 들어이 시도 :이 이용 약관의 법률 위반에 둘 것입니다 생각

http://www.google.com/search?hl=en&q=Stack+Overflow 
2

를 (! 그것에 대해 변호사와 상담 : 프로그래머가 법률 자문을 제공하는 잘되지 않습니다) 기술적으로, 그러나, 당신은 검색 할 수 foobar는 단지 URL http://www.google.com/search?q=foobar을 방문하여 결과 HTML을 스크랩하는 것으로 나타납니다. User-Agent HTTP 헤더와 어쩌면 다른 것을 가짜로 만들어야 할 수도 있습니다.

어쩌면 사용을 금지하는 검색 엔진이있을 수 있습니다. 당신과 당신의 변호사는 이것이 실제로 사실인지보기 위해 주변을 둘러 보도록 조언받을 것입니다.

0

Cygwin을 다운로드하고 경로에 Cygwin \ bin을 추가하면 curl을 사용하여 페이지를 검색하고 grep/sed/결과를 구문 분석 할 수 있습니다. 어쨌든 왜 검색어 문자열 매개 변수를 사용할 수 있습니까? 컬 (curl)을 사용하면 정보를 게시 할 수도 있고 헤더 정보를 설정할 수도 있습니다. 커맨드 라인에서 웹 서비스를 호출하는 데 사용합니다.

관련 문제