7

[Golang] Login Facebook and Take Screenshot Programmatically

 2 years ago
source link: http://siongui.github.io/2017/05/03/go-programmatically-login-facebook-and-take-screenshot/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

[Golang] Login Facebook and Take Screenshot Programmatically

May 03, 2017

I heard the news of headless Chrome from HN [1], and found that it is possible to write a Go program [3] to automatically web-scraping JavaScript rendered web pages via Chrome Debugging Protocol [2]. I have tried to use Python dryscrape to programmatically login a website before [4], and now I will try to use Go chromedp package to login Facebook and take screenshot programmatically.

Install Go chromedp package for programmatically drive the browser and simulate human user actions:

$ go get -u github.com/knq/chromedp

Install Go package for read password from console [5]:

$ go get -u golang.org/x/crypto/ssh/terminal

Login Facebook and Take Screenshot:

main.go | repository | view raw

package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"

	cdp "github.com/knq/chromedp"
	cdptypes "github.com/knq/chromedp/cdp"

	"golang.org/x/crypto/ssh/terminal"
	"syscall"
)

func getCredentials() (u, p string) {
	fmt.Print("Username: ")
	_, err := fmt.Scan(&u)
	if err != nil {
		panic(err)
	}

	fmt.Print("Password: ")
	password, err := terminal.ReadPassword(int(syscall.Stdin))
	if err != nil {
		panic(err)
	}
	p = string(password)

	return
}

func facebookLogin(username, password string) cdp.Tasks {
	selname := `//input[@id="email"]`
	selpass := `//input[@id="pass"]`
	var buf []byte

	return cdp.Tasks{
		cdp.Navigate(`https://www.facebook.com`),
		cdp.WaitVisible(selpass),
		cdp.SendKeys(selname, username),
		cdp.SendKeys(selpass, password),
		cdp.Submit(selpass),
		cdp.WaitVisible(`//a[@title="Profile"]`),
		cdp.CaptureScreenshot(&buf),
		cdp.ActionFunc(func(context.Context, cdptypes.Handler) error {
			return ioutil.WriteFile("myfb.png", buf, 0644)
		}),
	}
}

func main() {
	var err error

	// create context
	ctxt, cancel := context.WithCancel(context.Background())
	defer cancel()

	// create chrome instance
	c, err := cdp.New(ctxt, cdp.WithLog(log.Printf))
	if err != nil {
		log.Fatal(err)
	}

	// run task list
	err = c.Run(ctxt, facebookLogin(getCredentials()))
	if err != nil {
		log.Fatal(err)
	}

	// shutdown chrome
	err = c.Shutdown(ctxt)
	if err != nil {
		log.Fatal(err)
	}

	// wait for chrome to finish
	err = c.Wait()
	if err != nil {
		log.Fatal(err)
	}
}

Tested on: Ubuntu Linux 17.04, Go 1.8.1.


References:

[7]What's the recommended encryption library for Go? : golang

[8]Library for accessing the Pwned Passwords API : golang

[9]Question About Context Package : golang

[10]Validating elliptic curve signatures using Golang : golang


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK