Я пытаюсь использовать Go для входа в свою учетную запись на Amazon, чтобы автоматически получить некоторую информацию, но у меня возникают проблемы со входом, потому что он жалуется на файлы cookie. Вот очищенная версия кода, который я использовал:

package main

import (
"bytes"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
"strconv"
)

func CheckThis(AmazonUsername string, AmazonPassword string) error {

var LogonURL string

// Set the url
LogonURL = "https://www.amazon.com/ap/signin"

// Craft some form data
form := url.Values{}
form.Add("appAction", "SIGNIN")
form.Add("email", AmazonUsername)
form.Add("password", AmazonPassword)
form.Add("create", "0")
form.Add("appActionToken", “$VALUE”)
form.Add("openid.pape.max_auth_age", "$VALUE==")
form.Add("openid.identity", "$VALUE=")
form.Add("openid.assoc_handle", "$VALUE")
form.Add("openid.mode", "$VALUE")
form.Add("openid.ns.pape", "$VALUE==")
form.Add("openid.claimed_id", "$VALUE=")
form.Add("pageId", "$VALUE")
form.Add("openid.ns", "$VALUE=")

// Amazon sells cookies
cookieJar, _ := cookiejar.New(nil)

// Create a new client with the cookiejar in the struct...
client := &http.Client{
    Jar: cookieJar,
}

// Craft the request to send to the website with the form containing login info
req, _ := http.NewRequest("POST", LogonURL, bytes.NewBufferString(form.Encode()))

// Some more headers
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Content-Length", strconv.Itoa(len(form.Encode())))
req.Header.Add("Accept-Language", "en-US,en;q=0.8")
req.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
req.Header.Add("Connection", "keep-alive")
req.Header.Add("Host", "www.amazon.com")
req.Header.Add("Referer", "https://www.amazon.com/ap/signin")
req.Header.Add("Upgrade-Insecure-Requests", "1")
req.Header.Add("Origin", "https://www.amazon.com")
req.Header.Add("Cache-Control", "max-age=0")

// And we're off to the races...
resp, _ := client.Do(req)

// What was in the response?
charResponse, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()

// Write response body to a text file with title of…
_ = WriteOutputToFile(string(charResponse), “response.html")

// All done!
return nil
}

Записи $ VALUE вызваны тем, что я не уверен, важны ли строки для моей учетной записи, поэтому я удалил их; это значения, которые я извлек из инструментов разработчика сеанса входа в Chrome. Я также удалил проверки на ошибки для краткости.

Страница ответа (открытие response.html на моем диске в Chrome) выглядит так: Amazon Response

Что мне не хватает, чтобы сохранить файл cookie с клиентом req / resp для страницы входа и последующих страниц?

Или мне не хватает чего-то, где сохраняемая мной страница ответа пытается вытащить элементы из Amazon при рендеринге HTML, а проблема с файлами cookie связана с тем, что в браузере будет отсутствовать информация о файлах cookie, когда я пытаюсь просмотреть результаты из приложения Go ?

0
Bart Silverstrim 19 Фев 2016 в 21:27

2 ответа

Лучший ответ

Я почти уверен, что Amazon использует разные данные каждый раз, когда вы пытаетесь войти в систему, поэтому лучше проанализировать форму входа. Вот пример

package main

import (
    "bytes"
    "io/ioutil"
    "net/http"
    "net/http/cookiejar"
    "net/url"
    "github.com/PuerkitoBio/goquery"
    "log"
)

func checkError(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func CheckThis(AmazonUsername string, AmazonPassword string) error {
    cookieJar, _ := cookiejar.New(nil)

    client := &http.Client{
        Jar: cookieJar,
    }

    res, err := client.Get("https://www.amazon.com/gp/sign-in.html/ref=ord_cart_unrec_signin")
    checkError(err)

    doc, err := goquery.NewDocumentFromResponse(res)

    form := url.Values{}
    doc.Find("form[name='signIn'] input").Each(func(i int, s *goquery.Selection) {
        name, exist := s.Attr("name")
        if exist {
            value, exist := s.Attr("value")
            if exist {
                form.Add(name, value)
            }
        }

    })
    form.Set("email", AmazonUsername)
    form.Set("password", AmazonPassword)

    req, _ := http.NewRequest("POST", "https://www.amazon.com/ap/signin", bytes.NewBufferString(form.Encode()))
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

    res, err = client.Do(req)
    checkError(err)
    defer res.Body.Close()

    charResponse, _ := ioutil.ReadAll(res.Body)

    ioutil.WriteFile("response.html", charResponse, 0777)

    return nil
}

func main() {
    CheckThis("", "")
}
1
CrazyCrow 19 Фев 2016 в 19:05

Индекс Amazon устанавливает эти (и многие другие) файлы cookie в моем браузере:

amazon cookies

Я полагаю, вам нужно установить их в cookiejar, чтобы имитировать браузер (amazon исключает это из вашего запроса, поэтому сообщает, что у вас не включены файлы cookie, потому что нет требуемого значения безопасности).

Я согласен с @JimB, вы должны использовать Amazon SDK. Есть ли причина, по которой вы этого не делаете?

С уважением.

0
Cedmundo 19 Фев 2016 в 18:48