【问题标题】:Amazon blocked Python 3 scraping using bs4, requests亚马逊使用 bs4 阻止 Python 3 抓取,请求
【发布时间】:2020-03-12 06:12:54
【问题描述】:

几天前我运行这段代码时运行良好:

from bs4 import BeautifulSoup
import datetime
import requests

def getWeekMostRead(date):
    nonfiction_page = requests.get("https://www.amazon.com/charts/"+date.isoformat()+"/mostread/nonfiction")
    content = "amazon"+date.isoformat()+"_nonfiction.html"
    with open(content, "w", encoding="utf-8") as nf_file:
        print(nonfiction_page.content, file=nf_file)

    mostRead_nonfiction = BeautifulSoup(nonfiction_page.content, features="html.parser")

    nonfiction = mostRead_nonfiction.find_all("div", class_="kc-horizontal-rank-card")

    mostread = []
    for books in nonfiction:
        if books.find(class_="kc-rank-card-publisher") is None:
            mostread.append((
                books.find(class_="kc-rank-card-title").string.strip(),
                books.find(class_="kc-rank-card-author").string.strip(),
                "",
                books.find(class_="numeric-star-data").small.string.strip()
            ))
        else:
            mostread.append((
                books.find(class_="kc-rank-card-title").string.strip(),
                books.find(class_="kc-rank-card-author").string.strip(),
                books.find(class_="kc-rank-card-publisher").string.strip(),
                books.find(class_="numeric-star-data").small.string.strip()
            ))
    return mostread

mostread = []
date = datetime.date(2020,1,1)
while date >= datetime.date(2015,1,1):
    print("Scraped data from "+date.isoformat())
    mostread.extend(getWeekMostRead(date))
    date -= datetime.timedelta(7)
print("Currently saving scraped data to AmazonCharts.csv")
with open("AmazonCharts.csv", "w") as csv:
    counter = 0
    print("ID,Title,Author,Publisher,Rating", file=csv)
    for book in mostread:
        counter += 1
        print('AmazonCharts'+str(counter)+',"'+book[0]+'","'+book[1]+'","'+book[2]+'","'+book[3]+'"', file=csv)
    csv.close()

由于某种原因,今天我再次尝试运行它,结果我将它包含在返回的 HTML 文件中:

To discuss automated access to Amazon data please contact api-services-support@amazon.com.\r\n\r\nFor information about migrating to our APIs refer to our Marketplace APIs at https://developer.amazonservices.com/ref=rm_5_sv, or our Product Advertising API at https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html/ref=rm_5_ac for advertising use cases.

我知道亚马逊是一个沉重的反抓取数据(或者至少我从一些回复和线程中读到了这一点)。我尝试在代码中使用标题和延迟,但它不起作用。会有另一种方法来尝试这个吗?或者如果我应该等,我应该等多久?

【问题讨论】:

  • 他们可能已将您的 IP 地址记录为试图抓取他们的网站,因此延迟不太可能让您再次访问它。您是否考虑过按照他们的建议使用他们的 API?
  • 我确实尝试过抓取小说,但它确实有效 - 现在我正在研究如何为非小说制作它。问题是我正在为一个学校项目做这个,所以我可能不应该使用 API。 :(
  • 我收到此错误以获取 404 响应。但是有效的 URL 效果很好。可能你被列入黑名单。也可以考虑使用 User-Agent 标头。
  • 如果您正在为学校项目执行此操作,您应该考虑使用 API,因为抓取违反 Amazon 的使用政策,并且不仅可以获取您,还可以获取您学校中的每个人都被禁止访问他们的服务。
  • 只是一个问题。我可以浏览每个 HTML,将它们保存在本地,然后使用 bs4 根据保存的 HTML 抓取数据吗?

标签: python python-3.x web-scraping beautifulsoup


【解决方案1】:

正如您所说,亚马逊非常反对抓取。整个行业都是围绕从亚马逊抓取数据而建立的,亚马逊拥有自己的 API 访问权限来销售,因此阻止人们从他们的页面上随意抓取数据符合他们的最大利益。

根据您的代码,我怀疑您太快提出了太多请求并且被 IP 封禁。抓取网站时,通常最好负责任地抓取,不要太快、轮换用户代理和通过代理服务轮换 IP。

为了看起来不那么程序化,您还可以尝试随机化请求时间以看起来更人性化。

即便如此,您仍然可能会遇到此问题。亚马逊不是一个容易可靠抓取的网站。

【讨论】:

    【解决方案2】:

    您可以尝试在请求的标头中添加 User-Agent 使用这个

    headers = {
        'User-Agent': 'My User Agent 1.0',
        'From': 'personal@domain.com'  # This is another valid field
    }
    
    url = "YOURLINK"
    req = requests.get(url, headers=headers)
    

    应该没问题。

    【讨论】:

      【解决方案3】:

      过了一会儿,我想出了解决办法。这很简单 - 亚马逊上没有“2020-01-01”,而是我将其修复为“2020-01-05”。

      【讨论】:

        猜你喜欢
        • 2018-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-11
        • 2020-03-06
        • 1970-01-01
        • 2019-12-07
        • 1970-01-01
        相关资源
        最近更新 更多