我一直试图访问StackOverflow的数量为30请求/秒,但它不工作。它已被封锁后,几秒钟。虽然StackOverflow的文件说,StackExchange的最大速率限制是30请求/秒。
我用来访问的库是gocolly这里是我的代码:
package main
import (
"fmt"
"log"
"strconv"
"time"
"github.com/gocolly/colly"
"github.com/gocolly/colly/debug"
)
func finish() {
fmt.Println("Finish")
}
func main() {
c := colly.NewCollector(
colly.AllowedDomains("stackoverflow.com"),
colly.MaxDepth(1),
colly.Async(true),
colly.Debugger(&debug.LogDebugger{}),
)
c.Limit(&colly.LimitRule{DomainGlob: "*stackoverflow.*", Parallelism: 10, Delay: 1 * time.Second})
c.OnRequest(func(r *colly.Request) {
r.Headers.Set("User-Agent", "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")
})
c.OnError(func(_ *colly.Response, err error) {
log.Println("Something went wrong:", err)
})
c.OnResponse(func(r *colly.Response) {
fmt.Println("Visited", r.Request.URL)
})
c.OnHTML("#questions", func(e *colly.HTMLElement) {
e.ForEach(".s-post-summary.js-post-summary", func(i int, el *colly.HTMLElement) {
link := el.ChildAttr("a[href]", "href")
e.Request.Visit("https://stackoverflow.com" + link)
})
})
for i := 0; i <= 1000; i++ {
var link = "https://stackoverflow.com/questions?tab=votes&page=" + strconv.Itoa(i)
c.Visit(link)
c.Wait()
}
finish()
}
我希望有人能帮助我。
1条答案
按热度按时间2lpgd9681#
很遗憾,我无法在我的计算机上重现您的问题。顺便说一句,我将指出一些可以改进您的解决方案的事项。首先,让我分享一下我的工作解决方案:
所做的更改包括:
1.潜在并发线程从
10
减少到8
。1.使用我的
User-Agent
值。1.将
c.Wait
调用置于for
循环之外。最后一个修改是最重要的,因为你误解了它的用法。基本上,它等待之前创建的所有线程(例如,根据你的机器,你可能有
8
并发线程处理你的爬网请求)。如果你把这个语句放在循环中,每次你只等待刚刚示例化的线程导致同步操作。尝试几次就能很容易地注意到,如果把
c.Wait
留在for循环中,你会注意到页面是以有序的方式访问的;如果把这条语句从for
循环中去掉,页面是以无序的方式访问的。让我知道,如果这些变化也你的解决方案的作品,谢谢!