mirror of
https://github.com/PuerkitoBio/goquery.git
synced 2026-09-20 11:18:40 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d37930884 | ||
|
|
9551ee516e | ||
|
|
291e2cf4e3 | ||
|
|
7019296f03 | ||
|
|
eec8e87fed | ||
|
|
957a864443 | ||
|
|
34d91dbc67 | ||
|
|
0984c44bae | ||
|
|
fbfb78c352 | ||
|
|
e91ee4d790 | ||
|
|
90131ce208 | ||
|
|
3e5761b538 | ||
|
|
6802fc5555 | ||
|
|
466380eec7 | ||
|
|
0f5ed94072 | ||
|
|
3f0ba08339 | ||
|
|
629afd96a7 | ||
|
|
f1f5362a06 | ||
|
|
dd1e02fa62 | ||
|
|
f9e713566d | ||
|
|
fd5dc59310 | ||
|
|
b752fff338 | ||
|
|
8bd5b7d432 | ||
|
|
bf8e18a449 | ||
|
|
400486e492 | ||
|
|
1bc4a06d02 | ||
|
|
bc419c1e56 | ||
|
|
b076e25085 | ||
|
|
22d8cfd154 | ||
|
|
56c8ec7392 |
@@ -5,3 +5,8 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
# Enable version updates for GitHub action workflows
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
@@ -8,18 +8,18 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x, 1.22.x]
|
||||
go-version: [1.23.x]
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v3
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Test
|
||||
run: go test ./... -v -cover
|
||||
|
||||
@@ -22,7 +22,13 @@ Syntax-wise, it is as close as possible to jQuery, with the same function names
|
||||
|
||||
## Installation
|
||||
|
||||
Please note that starting with version `v1.9.0` of goquery, Go 1.18+ is required due to the use of generics. For previous goquery versions, a Go version of 1.1+ was required because of the `net/html` dependency. Ongoing goquery development is tested on the latest 2 versions of Go.
|
||||
Required Go version:
|
||||
|
||||
* Starting with version `v1.10.0` of goquery, Go 1.23+ is required due to the use of function-based iterators.
|
||||
* For `v1.9.0` of goquery, Go 1.18+ is required due to the use of generics.
|
||||
* For previous goquery versions, a Go version of 1.1+ was required because of the `net/html` dependency.
|
||||
|
||||
Ongoing goquery development is tested on the latest 2 versions of Go.
|
||||
|
||||
$ go get github.com/PuerkitoBio/goquery
|
||||
|
||||
@@ -40,6 +46,9 @@ Please note that starting with version `v1.9.0` of goquery, Go 1.18+ is required
|
||||
|
||||
**Note that goquery's API is now stable, and will not break.**
|
||||
|
||||
* **2024-09-06 (v1.10.0)** : Add `EachIter` which provides an iterator that can be used in `for..range` loops on the `*Selection` object. **goquery now requires Go version 1.23+** (thanks [@amikai](https://github.com/amikai)).
|
||||
* **2024-09-06 (v1.9.3)** : Update `go.mod` dependencies.
|
||||
* **2024-04-29 (v1.9.2)** : Update `go.mod` dependencies.
|
||||
* **2024-02-29 (v1.9.1)** : Improve allocation and performance of the `Map` function and `Selection.Map` method, better document the cascadia differences (thanks [@jwilsson](https://github.com/jwilsson)).
|
||||
* **2024-02-22 (v1.9.0)** : Add a generic `Map` function, **goquery now requires Go version 1.18+** (thanks [@Fesaa](https://github.com/Fesaa)).
|
||||
* **2023-02-18 (v1.8.1)** : Update `go.mod` dependencies, update CI workflow.
|
||||
@@ -160,6 +169,7 @@ func main() {
|
||||
- [goskyr](https://github.com/jakopako/goskyr), an easily configurable command-line scraper written in Go.
|
||||
- [goGetJS](https://github.com/davemolk/goGetJS), a tool for extracting, searching, and saving JavaScript files (with optional headless browser).
|
||||
- [fitter](https://github.com/PxyUp/fitter), a tool for selecting values from JSON, XML, HTML and XPath formatted pages.
|
||||
- [seltabl](github.com/conneroisu/seltabl), an orm-like package and supporting language server for extracting values from HTML
|
||||
|
||||
## Support
|
||||
|
||||
@@ -182,15 +192,15 @@ There are a number of ways you can support the project:
|
||||
|
||||
The [BSD 3-Clause license][bsd], the same as the [Go language][golic]. Cascadia's license is [here][caslic].
|
||||
|
||||
[jquery]: http://jquery.com/
|
||||
[go]: http://golang.org/
|
||||
[jquery]: https://jquery.com/
|
||||
[go]: https://go.dev/
|
||||
[cascadia]: https://github.com/andybalholm/cascadia
|
||||
[cascadiacli]: https://github.com/suntong/cascadia
|
||||
[bsd]: http://opensource.org/licenses/BSD-3-Clause
|
||||
[golic]: http://golang.org/LICENSE
|
||||
[bsd]: https://opensource.org/licenses/BSD-3-Clause
|
||||
[golic]: https://go.dev/LICENSE
|
||||
[caslic]: https://github.com/andybalholm/cascadia/blob/master/LICENSE
|
||||
[doc]: https://pkg.go.dev/github.com/PuerkitoBio/goquery
|
||||
[index]: http://api.jquery.com/index/
|
||||
[index]: https://api.jquery.com/index/
|
||||
[gonet]: https://github.com/golang/net/
|
||||
[html]: https://pkg.go.dev/golang.org/x/net/html
|
||||
[wiki]: https://github.com/PuerkitoBio/goquery/wiki/Tips-and-tricks
|
||||
|
||||
@@ -25,6 +25,48 @@ func BenchmarkEach(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEachIter(b *testing.B) {
|
||||
var tmp, n int
|
||||
|
||||
b.StopTimer()
|
||||
sel := DocW().Find("td")
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for range sel.EachIter() {
|
||||
tmp++
|
||||
}
|
||||
if n == 0 {
|
||||
n = tmp
|
||||
}
|
||||
}
|
||||
if n != 59 {
|
||||
b.Fatalf("want 59, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEachIterWithBreak(b *testing.B) {
|
||||
var tmp, n int
|
||||
|
||||
b.StopTimer()
|
||||
sel := DocW().Find("td")
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
tmp = 0
|
||||
for range sel.EachIter() {
|
||||
tmp++
|
||||
if tmp >= 10 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if n == 0 {
|
||||
n = tmp
|
||||
}
|
||||
}
|
||||
if n != 10 {
|
||||
b.Fatalf("want 10, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMap(b *testing.B) {
|
||||
var tmp, n int
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ func (s *Selection) AddBackFiltered(selector string) *Selection {
|
||||
}
|
||||
|
||||
// AddBackMatcher reduces the previous set of elements on the stack to those that match
|
||||
// the mateher, and adds them to the curernt set.
|
||||
// the matcher, and adds them to the current set.
|
||||
// It returns a new Selection object containing the current Selection combined
|
||||
// with the filtered previous one
|
||||
func (s *Selection) AddBackMatcher(m Matcher) *Selection {
|
||||
|
||||
@@ -2,7 +2,7 @@ module github.com/PuerkitoBio/goquery
|
||||
|
||||
require (
|
||||
github.com/andybalholm/cascadia v1.3.2
|
||||
golang.org/x/net v0.21.0
|
||||
golang.org/x/net v0.29.0
|
||||
)
|
||||
|
||||
go 1.18
|
||||
go 1.23
|
||||
|
||||
@@ -10,8 +10,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package goquery
|
||||
|
||||
import "iter"
|
||||
|
||||
// Each iterates over a Selection object, executing a function for each
|
||||
// matched element. It returns the current Selection object. The function
|
||||
// f is called for each element in the selection with the index of the
|
||||
@@ -12,6 +14,18 @@ func (s *Selection) Each(f func(int, *Selection)) *Selection {
|
||||
return s
|
||||
}
|
||||
|
||||
// EachIter returns an iterator that yields the Selection object in order.
|
||||
// The implementation is similar to Each, but it returns an iterator instead.
|
||||
func (s *Selection) EachIter() iter.Seq2[int, *Selection] {
|
||||
return func(yield func(int, *Selection) bool) {
|
||||
for i, n := range s.Nodes {
|
||||
if !yield(i, newSingleSelection(n, s.document)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EachWithBreak iterates over a Selection object, executing a function for each
|
||||
// matched element. It is identical to Each except that it is possible to break
|
||||
// out of the loop by returning false in the callback function. It returns the
|
||||
|
||||
@@ -105,3 +105,39 @@ func TestGenericMap(t *testing.T) {
|
||||
t.Errorf("Expected Map array result to have a length of 3, found %v.", len(vals))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEachIter(t *testing.T) {
|
||||
var cnt int
|
||||
|
||||
sel := Doc().Find(".hero-unit .row-fluid")
|
||||
|
||||
for i, s := range sel.EachIter() {
|
||||
cnt++
|
||||
t.Logf("At index %v, node %v", i, s.Nodes[0].Data)
|
||||
}
|
||||
|
||||
sel = sel.Find("a")
|
||||
|
||||
if cnt != 4 {
|
||||
t.Errorf("Expected Each() to call function 4 times, got %v times.", cnt)
|
||||
}
|
||||
assertLength(t, sel.Nodes, 6)
|
||||
}
|
||||
|
||||
func TestEachIterWithBreak(t *testing.T) {
|
||||
var cnt int
|
||||
|
||||
sel := Doc().Find(".hero-unit .row-fluid")
|
||||
for i, s := range sel.EachIter() {
|
||||
cnt++
|
||||
t.Logf("At index %v, node %v", i, s.Nodes[0].Data)
|
||||
break
|
||||
}
|
||||
|
||||
sel = sel.Find("a")
|
||||
|
||||
if cnt != 1 {
|
||||
t.Errorf("Expected Each() to call function 1 time, got %v times.", cnt)
|
||||
}
|
||||
assertLength(t, sel.Nodes, 6)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user