Files
openserp/yandex/search_raw.go

87 lines
2.2 KiB
Go
Raw Permalink Normal View History

2023-06-23 04:08:00 +03:00
package yandex
import (
"bytes"
"context"
"errors"
"fmt"
2023-06-23 04:08:00 +03:00
"github.com/PuerkitoBio/goquery"
2023-06-23 04:16:45 +03:00
"github.com/karust/openserp/core"
2023-06-23 04:08:00 +03:00
)
func classifyYandexRawHTML(body []byte) error {
doc, err := goquery.NewDocumentFromReader(bytes.NewReader(body))
if err != nil {
return err
2023-06-23 04:08:00 +03:00
}
if doc.Find(Selectors.Captcha).Length() > 0 {
return core.ErrCaptcha
2023-06-23 04:08:00 +03:00
}
if doc.Find(Selectors.NoResults).Length() > 0 {
return core.ErrEmptyResult
2023-06-23 04:08:00 +03:00
}
return nil
2023-06-23 04:08:00 +03:00
}
func Search(ctx context.Context, query core.Query) (results []core.SearchResult, err error) {
ctx = core.PrepareEngineContext(ctx, query, "yandex", false)
defer func() {
if recovered := recover(); recovered != nil {
err = core.RecoverEnginePanicWithContext(ctx, "yandex", recovered, nil)
results = nil
}
}()
startPage, skipOnFirstPage, err := core.ComputePagination(query.Start, 10)
if err != nil {
return nil, err
}
searchURL, err := BuildURL(query, startPage)
2023-06-23 04:08:00 +03:00
if err != nil {
return nil, err
}
core.WithRequest(ctx).WithField("url", searchURL).Debug(fmt.Sprintf("Yandex URL built: %s", searchURL))
2023-06-23 04:08:00 +03:00
res, err := core.RawSearchRequest(ctx, searchURL, query)
2023-06-23 04:08:00 +03:00
if err != nil {
return nil, err
}
defer core.DrainAndCloseResponse(res)
core.WithRequest(ctx).WithField("status_code", res.StatusCode).Debug(
fmt.Sprintf("Yandex Raw response: code=%d", res.StatusCode),
)
2023-06-23 04:08:00 +03:00
body, err := core.ReadRawSearchBody(res)
2023-06-23 04:08:00 +03:00
if err != nil {
return nil, err
}
htmlStatus := classifyYandexRawHTML(body)
if htmlStatus != nil && !errors.Is(htmlStatus, core.ErrEmptyResult) {
return nil, htmlStatus
}
parsedResults, err := ParseHTML(bytes.NewReader(body))
if err != nil {
return nil, err
}
if len(parsedResults) == 0 {
if errors.Is(htmlStatus, core.ErrEmptyResult) {
return []core.SearchResult{}, nil
}
return nil, fmt.Errorf("%w: yandex raw search returned no parseable results", core.ErrParser)
}
if skipOnFirstPage > 0 {
parsedResults = skipOrganicResults(parsedResults, skipOnFirstPage)
}
rebaseOrganicRanks(parsedResults, query.Start)
offsetAbsoluteRanks(parsedResults, startPage*10)
core.WithRequest(ctx).WithField("results_count", len(parsedResults)).Debug(
fmt.Sprintf("Yandex Raw results : %v", parsedResults),
)
2023-06-23 04:08:00 +03:00
return parsedResults, nil
2023-06-23 04:08:00 +03:00
}