Golang中如何遍历CSV文件并将数据存入API函数使用的变量
Golang中如何遍历CSV文件并将数据存入API函数使用的变量 我需要帮助。
目标:读取一个CSV文件(只包含一行数据)。每行是一个电话号码。程序将获取这个电话号码并将其插入到一个API中,然后将结果写入CSV文件。文件可能很大(数万个号码)。
我基本上有两段代码。一段读取CSV文件并将号码打印到屏幕上。另一段触发API并将结果打印到CSV文件中。我正在尝试将两者结合起来以获得我想要的结果,但遇到了困难。感谢任何帮助。
读取CSV文件的代码示例:
package main
import (
"encoding/csv"
"fmt"
"os"
)
type CsvLine struct {
Column1 string
}
func main() {
filename := "input.csv"
// 打开CSV文件
f, err := os.Open(filename)
if err != nil {
panic(err)
}
defer f.Close()
// 将文件读入变量
lines, err := csv.NewReader(f).ReadAll()
if err != nil {
panic(err)
}
// 遍历行并转换为对象
for _, line := range lines {
data := CsvLine{
Column1: line[0],
}
fmt.Println(data.Column1)
}
}
这段代码执行API查询:
package main
import (
"encoding/csv"
"encoding/json"
"fmt"
"log"
"os"
"strconv"
"strings"
"net/http"
"io/ioutil"
)
func decodeJson(m map[string]interface{}) []string {
values := make([]string, 0, len(m))
for _, v := range m {
switch vv := v.(type) {
case map[string]interface{}:
for _, value := range decodeJson(vv) {
values = append(values, value)
}
case string:
values = append(values, vv)
case float64:
values = append(values, strconv.FormatFloat(vv, 'f', -1, 64))
case []interface{}:
case bool:
values = append(values, strconv.FormatBool(vv))
case nil:
values = append(values, "nil")
}
}
return values
}
func carrierlookup() []byte {
url := "https://api.message360.com/api/v3/carrier/lookup.json"
payload := strings.NewReader("phoneNumber=")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Authorization", "Basic ")
req.Header.Add("Cache-Control", "no-cache")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
return body
}
func main() {
var d interface{}
err := json.Unmarshal(carrierlookup(), &d)
if err != nil {
log.Fatal("Failed to unmarshal")
}
values := decodeJson(d.(map[string]interface{}))
fmt.Println(values)
f, err := os.Create("outputfile.csv")
if err != nil {
log.Fatal("Failed to create outputfile.csv")
}
defer f.Close()
w := csv.NewWriter(f)
if err := w.Write(values); err != nil {
log.Fatal("Failed to write to file")
}
w.Flush()
if err := w.Error(); err != nil {
log.Fatal("Failed to flush outputfile.csv")
}
}
更多关于Golang中如何遍历CSV文件并将数据存入API函数使用的变量的实战教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的建议。我一直在尝试按照建议的方式使其工作。然而,我仍在学习通用编程的过程中——您能否稍微详细说明一下可能的格式是什么样的?
再次感谢您的所有帮助。
更多关于Golang中如何遍历CSV文件并将数据存入API函数使用的变量的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果您想以串行方式(而非并行)执行此操作,不应在第一个 main() 函数中直接打印,而应调用 carrierlookup() 函数(将其修改为 carrierlookup(phoneNumber string) 并利用该参数)。
返回的数据可以按照您在第二个 main() 函数中的处理方式进行解码,并写入结果 CSV 文件。
之后您就可以尝试使用两个通道和一些工作器来实现并行处理,这会很有趣…
以下是结合两段代码的解决方案,用于遍历CSV文件中的电话号码,调用API查询,并将结果写入新的CSV文件。该方案考虑了处理大文件时的内存效率,通过逐行读取而非一次性加载全部数据。
package main
import (
"encoding/csv"
"encoding/json"
"fmt"
"log"
"os"
"strconv"
"strings"
"net/http"
"io/ioutil"
)
type CsvLine struct {
Column1 string
}
func decodeJson(m map[string]interface{}) []string {
values := make([]string, 0, len(m))
for _, v := range m {
switch vv := v.(type) {
case map[string]interface{}:
for _, value := range decodeJson(vv) {
values = append(values, value)
}
case string:
values = append(values, vv)
case float64:
values = append(values, strconv.FormatFloat(vv, 'f', -1, 64))
case []interface{}:
// 处理数组情况,根据需要添加逻辑
case bool:
values = append(values, strconv.FormatBool(vv))
case nil:
values = append(values, "nil")
}
}
return values
}
func carrierlookup(phoneNumber string) []byte {
url := "https://api.message360.com/api/v3/carrier/lookup.json"
payload := strings.NewReader("phoneNumber=" + phoneNumber)
req, err := http.NewRequest("POST", url, payload)
if err != nil {
log.Fatal("Failed to create request: ", err)
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Authorization", "Basic YOUR_AUTH_TOKEN") // 替换为实际授权信息
req.Header.Add("Cache-Control", "no-cache")
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal("API request failed: ", err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal("Failed to read response body: ", err)
}
return body
}
func main() {
inputFilename := "input.csv"
outputFilename := "outputfile.csv"
// 打开输入CSV文件
inputFile, err := os.Open(inputFilename)
if err != nil {
log.Fatal("Failed to open input file: ", err)
}
defer inputFile.Close()
// 创建输出CSV文件
outputFile, err := os.Create(outputFilename)
if err != nil {
log.Fatal("Failed to create output file: ", err)
}
defer outputFile.Close()
reader := csv.NewReader(inputFile)
writer := csv.NewWriter(outputFile)
defer writer.Flush()
// 逐行读取输入文件
for {
line, err := reader.Read()
if err != nil {
if err.Error() == "EOF" {
break
}
log.Fatal("Error reading CSV line: ", err)
}
if len(line) == 0 {
continue
}
data := CsvLine{
Column1: line[0],
}
// 调用API查询
apiResponse := carrierlookup(data.Column1)
var jsonData interface{}
err = json.Unmarshal(apiResponse, &jsonData)
if err != nil {
log.Printf("Failed to unmarshal API response for %s: %v", data.Column1, err)
continue
}
values := decodeJson(jsonData.(map[string]interface{}))
// 写入结果到输出文件
if err := writer.Write(values); err != nil {
log.Fatal("Failed to write to output file: ", err)
}
}
if err := writer.Error(); err != nil {
log.Fatal("Error flushing output file: ", err)
}
fmt.Println("Processing completed. Results written to", outputFilename)
}
关键改进说明:
- 逐行处理:使用
reader.Read()替代ReadAll(),避免将整个文件加载到内存,适用于大文件。 - API集成:修改
carrierlookup函数以接受电话号码参数,并在主循环中为每个号码调用API。 - 错误处理:添加了API请求和响应的错误检查,确保程序在遇到问题时不会崩溃。
- 输出写入:在循环中逐行将API结果写入输出CSV文件,使用
defer writer.Flush()确保所有数据被写入。
注意:替换YOUR_AUTH_TOKEN为实际的API授权信息。根据API响应结构,可能需要调整decodeJson函数以正确提取所需字段。如果API返回数组结构,需在case []interface{}分支中添加处理逻辑。

