Golang如何通过代码自动填写Google表单

2 回复

我正在尝试以下解决方案:

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func HTTP(url string) (string, error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("GET error: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Status error: %v", resp.StatusCode)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("Read body: %v", err)
	}

	return string(data), nil
}
func main() {
	fmt.Println("\nEnter your name")
	var name string
	fmt.Scan(&name)

	fmt.Println("\nEnter email:")
	var emailreponse string
	fmt.Scan(&emailreponse)

	HTTP_0 := "https://docs.google.com/forms/d/e/1FAIpQLSfd8LRjHq4lRdWDb64hoBzTLGaNPn4TLeE5G-2Fp3HhJVcmmg/"
	HTTP_1 := "formResponse?&submit=Submit?"
	HTTP_2 := "usp=pp_url"
	Entry_0 := "&entry.194375880=" + name
	Entry_1 := "&entry.2012222327=" + emailreponse


	FormResponse, _ := HTTP(HTTP_0 + HTTP_1 + HTTP_2 + Entry_0 + Entry_1)

	fmt.Println(FormResponse)

}

我将表单改成了这个:https://forms.gle/pevmW2QHyg9QdeDc9,其中电子邮件不是自动收集的。

但我不知道如何发送这个URL,我认为使用Get方法不是正确的方法,对吗?

更多关于Golang如何通过代码自动填写Google表单的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中通过代码自动填写Google表单,可以通过HTTP POST请求直接提交表单数据。以下是实现方法:

核心实现步骤

  1. 分析表单结构:首先需要检查Google表单的字段名称
  2. 构造POST请求:向表单提交端点发送数据
  3. 处理响应:验证提交是否成功

示例代码

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "strings"
)

func submitGoogleForm() error {
    // Google表单提交URL(需要从实际表单页面获取)
    formURL := "https://docs.google.com/forms/d/e/YOUR_FORM_ID/formResponse"
    
    // 表单字段名称(通过检查HTML源码获取)
    // 例如:entry.1234567890 对应表单的第一个问题
    formData := url.Values{
        "entry.1234567890": {"你的答案1"},  // 替换为实际的entry ID和答案
        "entry.9876543210": {"你的答案2"},  // 替换为实际的entry ID和答案
        "entry.5555555555": {"选项1"},     // 对于选择题
    }
    
    // 创建HTTP客户端
    client := &http.Client{}
    
    // 发送POST请求
    resp, err := client.PostForm(formURL, formData)
    if err != nil {
        return fmt.Errorf("提交失败: %v", err)
    }
    defer resp.Body.Close()
    
    // 检查响应状态
    if resp.StatusCode != http.StatusOK {
        return fmt.Errorf("服务器返回错误状态: %s", resp.Status)
    }
    
    fmt.Println("表单提交成功")
    return nil
}

func main() {
    if err := submitGoogleForm(); err != nil {
        fmt.Printf("错误: %v\n", err)
    }
}

获取表单字段ID的方法

// 辅助函数:获取表单字段信息
func inspectFormStructure(formURL string) {
    resp, err := http.Get(formURL)
    if err != nil {
        fmt.Printf("获取表单失败: %v\n", err)
        return
    }
    defer resp.Body.Close()
    
    // 这里可以解析HTML,查找包含"entry."的字段名
    // 实际使用时可能需要使用goquery等HTML解析库
    fmt.Println("检查表单HTML源码,查找类似'entry.xxxxxxxxxx'的字段名")
}

完整示例(包含错误处理)

package main

import (
    "bytes"
    "fmt"
    "io"
    "net/http"
)

type FormSubmitter struct {
    FormID    string
    EntryData map[string]string
}

func NewFormSubmitter(formID string) *FormSubmitter {
    return &FormSubmitter{
        FormID:    formID,
        EntryData: make(map[string]string),
    }
}

func (fs *FormSubmitter) AddAnswer(entryID, answer string) {
    fs.EntryData[entryID] = answer
}

func (fs *FormSubmitter) Submit() error {
    submitURL := fmt.Sprintf("https://docs.google.com/forms/d/e/%s/formResponse", fs.FormID)
    
    // 构建表单数据
    formData := make([]string, 0, len(fs.EntryData))
    for entryID, answer := range fs.EntryData {
        formData = append(formData, fmt.Sprintf("%s=%s", entryID, url.QueryEscape(answer)))
    }
    
    body := strings.Join(formData, "&")
    
    // 创建请求
    req, err := http.NewRequest("POST", submitURL, bytes.NewBufferString(body))
    if err != nil {
        return fmt.Errorf("创建请求失败: %v", err)
    }
    
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("User-Agent", "Mozilla/5.0")
    
    // 发送请求
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return fmt.Errorf("发送请求失败: %v", err)
    }
    defer resp.Body.Close()
    
    // 读取响应
    responseBody, _ := io.ReadAll(resp.Body)
    if resp.StatusCode >= 400 {
        return fmt.Errorf("提交失败,状态码: %d, 响应: %s", resp.StatusCode, string(responseBody))
    }
    
    fmt.Printf("提交成功,响应长度: %d bytes\n", len(responseBody))
    return nil
}

func main() {
    // 使用示例
    submitter := NewFormSubmitter("YOUR_ACTUAL_FORM_ID")
    
    // 添加答案(需要替换为实际的entry ID)
    submitter.AddAnswer("entry.1234567890", "John Doe")
    submitter.AddAnswer("entry.9876543210", "john@example.com")
    submitter.AddAnswer("entry.5555555555", "选项A")
    
    if err := submitter.Submit(); err != nil {
        fmt.Printf("提交失败: %v\n", err)
    }
}

注意事项

  1. 获取正确的表单ID:从你的表单URL中提取/e/后面的部分
  2. 查找entry ID:在浏览器中查看表单页面源码,搜索entry.开头的字段名
  3. 编码问题:确保对答案进行URL编码
  4. 请求头:设置合适的User-Agent可以避免被拒绝

要获取你具体表单的entry ID,可以:

  • 在浏览器中打开表单
  • 右键查看页面源码
  • 搜索entry.查找所有表单字段ID

对于你提供的表单链接,需要先访问该链接,查看HTML源码获取实际的entry ID,然后替换示例代码中的字段名。

回到顶部