Python 网页抓取谷歌搜索结果

Python 网页抓取谷歌搜索结果,python,web-scraping,beautifulsoup,web-crawler,Python,Web Scraping,Beautifulsoup,Web Crawler,我正在一页一页地抓取谷歌学者搜索结果。在一定数量的页面之后,一个验证码弹出并中断我的代码。我读到谷歌限制了我每小时可以提出的请求。有办法绕过这个限制吗?我读了一些关于API的文章,但我不确定这是否有用 我感觉到了你的痛苦,因为我过去从谷歌上抓取过。为了完成我的工作,我尝试了以下几件事。这个列表是从最简单的技术到最难的技术排序的 每秒限制您的请求:谷歌和许多其他网站将每秒识别来自同一台机器的大量请求,并自动阻止它们,作为对您的防御措施。你所需要做的就是保持温和,例如,每1-5秒只做一次请求,以避

我正在一页一页地抓取谷歌学者搜索结果。在一定数量的页面之后,一个验证码弹出并中断我的代码。我读到谷歌限制了我每小时可以提出的请求。有办法绕过这个限制吗?我读了一些关于API的文章,但我不确定这是否有用

我感觉到了你的痛苦,因为我过去从谷歌上抓取过。为了完成我的工作,我尝试了以下几件事。这个列表是从最简单的技术到最难的技术排序的

  • 每秒限制您的请求:谷歌和许多其他网站将每秒识别来自同一台机器的大量请求,并自动阻止它们,作为对您的防御措施。你所需要做的就是保持温和,例如,每1-5秒只做一次请求,以避免很快被禁止
  • 随机化您的睡眠时间:让您的代码睡眠1秒钟太容易被检测为脚本。让它在每次迭代中随机休眠一段时间。显示了如何将其随机化的示例
  • 使用启用Cookie的web scraper库:如果您从头开始编写刮码,Google会注意到您的请求不会返回它收到的Cookie。使用一个好的库,例如来规避这个问题
  • 使用多个IP地址:节流肯定会降低刮取吞吐量。如果你真的需要快速抓取数据,你需要使用几个IP地址以避免被禁止。有几家公司在互联网上以一定的价格提供这种服务。我使用过并且非常喜欢它们的质量、文档和客户支持
  • 使用真正的浏览器:如果scraper不处理JavaScript或没有图形界面,一些网站会识别你的scraper。例如,使用具有的真实浏览器将解决此问题

你也可以看看,这是为纽约大学的网络搜索引擎课程编写的。它本身并不刮谷歌,但包含上述一些技术,如限制和随机分配睡眠时间。

来自刮谷歌学者的个人经验。45秒足以避免验证码和机器人检测。我有一台铲运机在没有检测到的情况下运行了3天以上。如果您确实被标记,等待大约2小时就足以重新开始


谷歌没有为Scholarotate代理和用户代理提供API,以避免来自谷歌的阻止请求。我想知道您是否可以就如何设置
global\u config
program\u logger
提供建议?我尝试了
pip安装
,但对我来说不起作用。我在R中寻找一个解决方案,但我看到了您的Python解决方案,所以我正在努力让它发挥作用,尽管我的Python技能相当薄弱。另外,我想知道如何输入要搜索的关键字字符串?
class ScholarScrape():
    def __init__(self):
        self.page = None
        self.last_url = None
        self.last_time = time.time()
        self.min_time_between_scrape = int(ConfigFile.instance().config.get('scholar','bot_avoidance_time'))
        self.header = {'User-Agent':ConfigFile.instance().config.get('scholar','user_agent')}
        self.session = requests.Session()
        pass

    def search(self, query=None, year_lo=None, year_hi=None, title_only=False, publication_string=None, author_string=None, include_citations=True, include_patents=True):
        url = self.get_url(query, year_lo, year_hi, title_only, publication_string, author_string, include_citations, include_patents)
        while True:
            wait_time = self.min_time_between_scrape - (time.time() - self.last_time)
            if wait_time > 0:
                logger.info("Delaying search by {} seconds to avoid bot detection.".format(wait_time))
                time.sleep(wait_time)
            self.last_time = time.time()
            logger.info("SCHOLARSCRAPE: " + url)
            self.page = BeautifulSoup(self.session.get(url, headers=self.header).text, 'html.parser')
            self.last_url = url

            if "Our systems have detected unusual traffic from your computer network" in str(self.page):
                raise BotDetectionException("Google has blocked this computer for a short time because it has detected this scraping script.")

            return

    def get_url(self, query=None, year_lo=None, year_hi=None, title_only=False, publication_string=None, author_string=None, include_citations=True, include_patents=True):
        base_url = "https://scholar.google.com.au/scholar?"
        url = base_url + "as_q=" + urllib.parse.quote(query)

        if year_lo is not None and bool(re.match(r'.*([1-3][0-9]{3})', str(year_lo))):
            url += "&as_ylo=" + str(year_lo)

        if year_hi is not None and bool(re.match(r'.*([1-3][0-9]{3})', str(year_hi))):
            url += "&as_yhi=" + str(year_hi)

        if title_only:
            url += "&as_yhi=title"
        else:
            url += "&as_yhi=any"

        if publication_string is not None:
            url += "&as_publication=" + urllib.parse.quote('"' + str(publication_string) + '"')

        if author_string is not None:
            url += "&as_sauthors=" + urllib.parse.quote('"' + str(author_string) + '"')

        if include_citations:
            url += "&as_vis=0"
        else:
            url += "&as_vis=1"

        if include_patents:
            url += "&as_sdt=0"
        else:
            url += "&as_sdt=1"

        return url

    def get_results_count(self):
        e = self.page.findAll("div", {"class": "gs_ab_mdw"})
        try:
            item = e[1].text.strip()
        except IndexError as ex:
            if "Our systems have detected unusual traffic from your computer network" in str(self.page):
                raise BotDetectionException("Google has blocked this computer for a short time because it has detected this scraping script.")
            else:
                raise ex

        if self.has_numbers(item):
            return self.get_results_count_from_soup_string(item)
        for item in e:
            item = item.text.strip()
            if self.has_numbers(item):
                return self.get_results_count_from_soup_string(item)
        return 0

    @staticmethod
    def get_results_count_from_soup_string(element):
        if "About" in element:
            num = element.split(" ")[1].strip().replace(",","")
        else:
            num = element.split(" ")[0].strip().replace(",","")
        return num

    @staticmethod
    def has_numbers(input_string):
        return any(char.isdigit() for char in input_string)


class BotDetectionException(Exception):
    pass

if __name__ == "__main__":
    s = ScholarScrape()
    s.search(**{
        "query":"\"policy shaping\"",
        # "publication_string":"JMLR",
        "author_string": "gilboa",
        "year_lo": "1995",
        "year_hi": "2005",

    })
    x = s.get_results_count()
    print(x)