如何使用 requests_html、Beautiful Soup 绕过 AKAMAI 机器人检测以进行数据抓取

How to bypass AKAMAI bot detection for data scraping using requests_html, Beautiful Soup

我正在从 Rakuten Japanese e-commerce website. I am using requests-html and Beautiful soup 抓取数据。 问题是当我从我的本地电脑 (127.0.0.1) 请求时它工作正常。但是当我从我的 ec2 服务器请求得到 Reference #<esi:vars name="AKAMAI_DEBUG_STRING"/> 这条消息时,没有找到数据或 HTML 页面。另一种情况是,当我使用 wget 并从服务器请求页面 URL 时,我得到了一个完整的页面。但是我的脚本不起作用。

这是我的代码示例:

from bs4 import BeautifulSoup
from requests_html import HTMLSession

def get_search_url(query_keyword):
    base_url = 'https://search.rakuten.co.jp/search/mall/'
    headers = {
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36',
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
    }
    session = HTMLSession()
    session.headers.update(headers)

    request_url = base_url + query_keyword
    resp = session.get(request_url)
    soup = BeautifulSoup(resp.text, "lxml")
    return soup

def feature_product_details(url):
    output_list = []
    for i in url.find_all("div", attrs={"class": "dui-card searchresultitem"}):
        product_title = i.find("div", attrs={"class": "content title"})
        if product_title is not None:
            product_title = product_title.getText()
        else:
            product_title = ""

        output = {
            'title': product_title,
        }
        output_list.append(output)
    print(output_list)
    return output_list

def main_rakuten_product_search(query):
    query_keyword = query
    page = get_search_url(query_keyword)
    product_lists = feature_product_details(page)
    return product_lists

if __name__ == '__main__':
    queries = '【レビュー特典中】スマートキー 電波遮断ケース 電波遮断ボックス リレーアタック防止用 キーケース '
    main_rakuten_product_search(queries)

当 运行 本地服务器时的示例输出:

[
    {
        "title": "【レビュー特典中】スマートキー 電波遮断ケース 電波遮断ボックス リレーアタック防止用 キーケース リレーアタック対策 ボックス 箱 電波遮断ケース RFIDブロッキング 高級PUレザー 高級車盗難防止 カーセキュリティ 高級感溢れ レクサス(グレー)",
    }
]

But don't get any response when running it on my server: Just show this message Reference #<esi:vars name="AKAMAI_DEBUG_STRING"/>

如果有人知道如何做到这一点,我将不胜感激。

我已经在 ap-northeast-1(东京)的 EC2 上尝试了你的代码,我得到了示例输出。

所以,这里有几件事要检查:

  • 确保您的 EC2 已打开正确的端口
  • 仔细检查 headers(我稍微修改了你的 - 请参阅下面的代码)
  • 检查您的查询输入;也许其中一些格式不正确?
  • 不要从一个 EC2 向 Rakuten 服务器发送过多请求;也许他们已经在阻止你了

这是经过一些微调后的代码:

from bs4 import BeautifulSoup
from requests_html import HTMLSession


def get_search_url(query_keyword):
    base_url = 'https://search.rakuten.co.jp/search/mall/'
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36',
        'referer': 'https://www.rakuten.co.jp/'
    }
    session = HTMLSession()
    session.headers.update(headers)
    return BeautifulSoup(session.get(base_url + query_keyword).content, "lxml")


def feature_product_details(url):
    output_list = []
    for i in url.find_all("div", attrs={"class": "dui-card searchresultitem"}):
        product_title = i.find("div", attrs={"class": "content title"})
        if product_title is not None:
            product_title = product_title.getText()
        else:
            product_title = ""
        output_list.append({'title': product_title})
    return output_list


def main_rakuten_product_search(query):
    return feature_product_details(get_search_url(query))


if __name__ == '__main__':
    queries = '【レビュー特典中】スマートキー 電波遮断ケース 電波遮断ボックス リレーアタック防止用 キーケース '
    print(main_rakuten_product_search(queries))