inou/scrape_mychart/main.go

95 lines
2.2 KiB
Go
Executable File

package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
func main() {
// Read config
cookie := os.Getenv("MYCHART_COOKIE")
token := os.Getenv("MYCHART_TOKEN")
nonce := os.Getenv("MYCHART_NONCE")
if cookie == "" || token == "" || nonce == "" {
fmt.Println("Set environment variables:")
fmt.Println(" MYCHART_COOKIE - full Cookie header value")
fmt.Println(" MYCHART_TOKEN - __RequestVerificationToken header")
fmt.Println(" MYCHART_NONCE - PageNonce value from request body")
os.Exit(1)
}
// Read keys from file
keysFile, err := os.Open("keys.txt")
if err != nil {
fmt.Println("Create keys.txt with one key per line")
os.Exit(1)
}
defer keysFile.Close()
var keys []string
scanner := bufio.NewScanner(keysFile)
for scanner.Scan() {
key := strings.TrimSpace(scanner.Text())
if key != "" {
keys = append(keys, key)
}
}
fmt.Printf("Loaded %d keys\n", len(keys))
// Create output dir
os.MkdirAll("output", 0755)
client := &http.Client{Timeout: 30 * time.Second}
url := "https://mychart.hopkinsmedicine.org/MyChart/api/test-results/GetDetails"
for i, key := range keys {
outFile := filepath.Join("output", fmt.Sprintf("%03d.json", i))
if _, err := os.Stat(outFile); err == nil {
fmt.Printf("[%d/%d] skip %s\n", i+1, len(keys), key[:20])
continue
}
body := map[string]string{
"orderKey": key,
"organizationID": "",
"PageNonce": nonce,
}
jsonBody, _ := json.Marshal(body)
req, _ := http.NewRequest("POST", url, bytes.NewReader(jsonBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Cookie", cookie)
req.Header.Set("__RequestVerificationToken", token)
resp, err := client.Do(req)
if err != nil {
fmt.Printf("[%d/%d] ERROR %s: %v\n", i+1, len(keys), key[:20], err)
continue
}
data, _ := io.ReadAll(resp.Body)
resp.Body.Close()
if resp.StatusCode != 200 {
fmt.Printf("[%d/%d] HTTP %d %s\n", i+1, len(keys), resp.StatusCode, key[:20])
continue
}
os.WriteFile(outFile, data, 0644)
fmt.Printf("[%d/%d] OK %s\n", i+1, len(keys), key[:20])
time.Sleep(100 * time.Millisecond)
}
fmt.Println("Done")
}