【问题标题】:How to scrape multiple google pages with Python and BeautifulSoup如何使用 Python 和 BeautifulSoup 抓取多个谷歌页面
【发布时间】:2023-03-20 02:03:01
【问题描述】:

我写了一个可以抓取谷歌新闻搜索结果的代码。但它总是只刮第一页。 如何编写一个允许我抓取前 2,3...n 页的循环?

我知道在url中需要为页面添加参数,并全部放入for loop,但不知道怎么做?

此代码为我提供了第一个搜索页面的标题、段落和日期:

from bs4 import BeautifulSoup
import requests

headers = {'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

term = 'usa'
url = 'https://www.google.com/search?q={0}&source=lnms&tbm=nws'.format(term)# i know that I need to add this parameter for page, but I  do not know how

response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')

headline_text = soup.find_all('h3', class_= "r dO0Ag")

snippet_text = soup.find_all('div', class_='st')

news_date = soup.find_all('div', class_='slp')

另外,google news 和页面的这个逻辑可以应用于例如bing newsyahoo news,我的意思是,我可以使用相同的参数还是url 不同?

【问题讨论】:

  • 小心,因为google有一些强大的防刮措施,你可能会被屏蔽。如果您不想开发非常安全的抓取工具(IP 轮换、人体移动复制等),您可以考虑使用 Google 的 API 之一来获取您的数据
  • 你可以做url = 'https://www.google.com/search?q={0}&source=lnms&tbm=nws&page={1}'.format(term,page)看看stackoverflow.com/questions/38635419/…
  • 我试过了,但它总是返回我的第一页,我可以为页面输入任何数字,它总是返回我第 1 页的内容

标签: python beautifulsoup


【解决方案1】:

我认为您需要更改您的网址。试试下面的代码看看是否可行。

from bs4 import BeautifulSoup
import requests

headers = {'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

term = 'usa'
page=0


while True:
    url = 'https://www.google.com/search?q={}&tbm=nws&sxsrf=ACYBGNTx2Ew_5d5HsCvjwDoo5SC4U6JBVg:1574261023484&ei=H1HVXf-fHfiU1fAP65K6uAU&start={}&sa=N&ved=0ahUKEwi_q9qog_nlAhV4ShUIHWuJDlcQ8tMDCF8&biw=1280&bih=561&dpr=1.5'.format(term,page)
    print(url)

    response = requests.get(url, headers=headers,verify=False)
    if response.status_code!=200:
        break
    soup = BeautifulSoup(response.text, 'html.parser')

    headline_text = soup.find_all('h3', class_= "r dO0Ag")

    snippet_text = soup.find_all('div', class_='st')

    news_date = soup.find_all('div', class_='slp')
    page=page+10

【讨论】:

  • 它现在可以工作了,但是没有这么长的网址有没有办法做到这一点?我的意思是,如果我只想要第 1 页,则 url 短 3 曲。此外,这个网址如何查找 yahoo 和 bing
  • 那么request可能对你没有帮助。那么你必须使用像selenium WebDriver这样的浏览器工具并点击每个分页链接来获取新的页面值。
  • @taga:如果您有任何新的研究并且发现了问题,请发布一个新问题并提及您的目标。如果我不是其他贡献者,一定会帮助您。谢谢。
  • 嘿,你能帮我解决这个问题吗? stackoverflow.com/questions/59047342/…
【解决方案2】:

要测试的代码和full example in the online IDE

from bs4 import BeautifulSoup
import requests, urllib.parse

def paginate(url, previous_url=None):
    # Break from infinite recursion
    if url == previous_url: return

    headers = {
        "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3538.102 Safari/537.36 Edge/18.19582"
    }

    response = requests.get(url, headers=headers).text
    soup = BeautifulSoup(response, 'lxml')

    # First page
    yield soup

    next_page_node = soup.select_one('a#pnnext')

    # Stop when there is no next page
    if next_page_node is None: return

    next_page_url = urllib.parse.urljoin('https://www.google.com/',
                                         next_page_node['href'])

    # Pages after the first one
    yield from paginate(next_page_url, url)


def scrape():
    pages = paginate(
        "https://www.google.com/search?hl=en-US&q=coca+cola&tbm=nws")

    for soup in pages:
        print(f'Current page: {int(soup.select_one(".YyVfkd").text)}')
        print()

        for data in soup.findAll('div', class_='dbsr'):
            title = data.find('div', class_='JheGif nDgy9d').text
            link = data.a['href']

            print(f'Title: {title}')
            print(f'Link: {link}')
            print()


或者,您可以使用来自 SerpApi 的 Google News Results API 来实现相同的目的。这是一个带有免费计划的付费 API。

您的情况的不同之处在于它支持多个搜索引擎,并且设置过程快速而直接。您不必维护解析器或弄清楚如何绕过来自 Google 或其他引擎的块或如何提取某些元素,因为它已经为最终用户完成了。

要集成的代码:

# https://github.com/serpapi/google-search-results-python
from serpapi import GoogleSearch
import os

def scrape():
  params = {
    "engine": "google",
    "q": "gta san andreas",
    "tbm": "nws",
    "api_key": os.getenv("API_KEY"),
  }

  search = GoogleSearch(params)
  pages = search.pagination()

  for result in pages:
    print(f"Current page: {result['serpapi_pagination']['current']}")

    for news_result in result["news_results"]:
        print(f"Title: {news_result['title']}\nLink: {news_result['link']}\n")

P.S - 我写了一篇关于如何抓取Google News 的更详细的博文。

免责声明,我为 SerpApi 工作。

【讨论】:

    猜你喜欢
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2019-07-18
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    相关资源
    最近更新 更多