sq

a simple, powerful scraping library

  • 所有者: emptyinterface/sq
  • 平台:
  • 许可证: MIT License
  • 分类:
  • 主题:
  • 喜欢:
    0
      比较:

Github星跟踪图

sq

sq is a very simple, powerful scraping library

sq uses struct tags as configuration, reflection, and goquery to unmarshall data out of HTML pages.

type ExamplePage struct {
	Title string `sq:"title, text"`

	Users []struct {
		ID        int       `sq:"td:nth-child(1), text, regexp(\\d+)"`
		Name      string    `sq:"td:nth-child(2), text"`
		Email     string    `sq:"td:nth-child(3) a, attr(href), regexp(mailto:(.+))"`
		Website   *url.URL  `sq:"td:nth-child(4) > a, attr(href)"`
		Timestamp time.Time `sq:"td:nth-child(5), text, time(2006 02 03)"`
		RowMarkup string    `sq:" ., html"`
	} `sq:"table tr"`

	Stylesheets []*css.Stylesheet `sq:"style"`
	Javascripts []*ast.Program    `sq:"script [type$=javascript]"`

	HTMLSnippet      *html.Node         `sq:"div.container"`
	GoquerySelection *goquery.Selection `sq:"[href], [src]"`
}

resp, err := http.Get("https://example.com")
if err != nil {
	log.Fatal(err)
}
defer resp.Body.Close()

var p ExamplePage

// Scrape continues on error and returns a slice of errors that occurred.
errs := sq.Scrape(&p, resp.Body)
for _, err := range errs {
	fmt.Println(err)
}

Note: go struct tags are parsed as strings and so all backslashes must be escaped. (ie. \d+ -> \\d+)

Accessors, Parsers, and Loaders

Accessors, parsers, loaders are specified in the tag in a unix-style pipeline.

Accessors

  • text: The text accessor emits the result of goquery's Text() method on the matched Selection.
  • html: The html accessor emits the result of goquery's Html() method on the matched Selection.
  • attr(<attr>): The attr() accessor emits the result of goquery's Attr() method with the supplied argument on the matched Selection. An error will be returned if the specified attribute is not found.

Parsers

  • regexp(<regexp>): The regexp parser takes a regular expression and applies it to the input emitted by the previous accessor or parser function. When no subcapture group is specified, the first match is emitted. If a subcapture group is specified, the first subcapture is returned.

Loaders

  • time(<format>): The time() loader calls time.Parse() with the supplied format on the input emitted from the previous accessor or parser function.

Custom parsers and loaders may be added or overridden:

// unescapes content
sq.RegisterParseFunc("unescape", func(s, _ string) (string, error) {
	return html.UnescapeString(s), nil
})

// loads a time.Duration from a datestamp
sq.RegisterLoadFunc("age", func(_ *goquery.Selection, s, layout string) (interface{}, error) {
	t, err := time.Parse(layout, s)
	if err != nil {
		return nil, err
	}
	return time.Since(t), nil
})

// example use
type Page struct {
	Alerts []struct {
		Title string        `sq:"h3, text"`
		Age   time.Duration `sq:"span.posted, unescape, age(2006 02 03 15:04:05 MST)"`
	} `sq:"div.alert"`
}

Types

sq supports the full list of native go types except map, func, chan, and complex.

Several web related datastructures are also detected and loaded:

Each of these types are detected and loaded automatically using a TypeLoader. Overriding or adding type loaders is simple.

A TypeLoader is a pair of functions with a name. It takes function that checks for a match, and a function that does the loading.

// This is the typeloader for detecting url.URLs and loading them.
sq.RegisterTypeLoader("url",
	func(t reflect.Type) bool {
		return t.PkgPath() == "net/url" && t.Name() == "URL"
	},
	func(_ *goquery.Selection, s string) (interface{}, error) {
		return url.Parse(s)
	},
)

Docs

godoc

License

MIT 2016

主要指标

概览
名称与所有者emptyinterface/sq
主编程语言Go
编程语言Go (语言数: 1)
平台
许可证MIT License
所有者活动
创建于2016-06-09 20:27:30
推送于2019-01-11 22:51:32
最后一次提交2019-01-11 17:51:28
发布数0
用户参与
星数18
关注者数2
派生数1
提交数5
已启用问题?
问题数0
打开的问题数0
拉请求数0
打开的拉请求数1
关闭的拉请求数0
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?