我们如何导航到一个网页,抓取数据,移动到下一页,然后再做一次?

Posted

技术标签:

【中文标题】我们如何导航到一个网页,抓取数据,移动到下一页,然后再做一次?【英文标题】:How can we naviagte to a web page, scrape data, move to the next page, and do it again? 【发布时间】:2021-05-31 15:28:51 【问题描述】:

我做了两次尝试让我的代码导航到网页,将数据从表中导入数据框,然后移动到下一页并再次执行相同的操作。下面是我测试的一些示例代码。现在我被困住了;不知道如何继续。

# first attempt
import requests
from bs4 import BeautifulSoup
import pandas as pd
from selenium import webdriver
from time import sleep

lst = []
url = "https://www.nasdaq.com/market-activity/stocks/screener"

for numb in (1, 10):
    url = "https://www.nasdaq.com/market-activity/stocks/screener"
    r = requests.get(url)
    html = r.text
    soup = BeautifulSoup(html, "html.parser")
    table = soup.find_all('table')
    df = pd.DataFrame(table)
    lst.append(df)
    
    def get_cpf():
        driver = webdriver.Chrome("C:/Utility/chromedriver.exe")
        driver.get(url)
        driver.find_element_by_class('pagination__page" data-page="'' +  numb + ''').click()
        sleep(10)
        text=driver.find_element_by_id('texto_cpf').text
        print(text)
    get_cpf()
    get_cpf.click
    

### second attempt
#import BeautifulSoup
from bs4 import BeautifulSoup
import pandas as pd
import requests
from selenium import webdriver
from time import sleep

lst = []

for numb in (1, 10):
    r=requests.get('https://www.nasdaq.com/market-activity/stocks/screener')
    data = r.text
    soup = BeautifulSoup(data, "html.parser")
    table = soup.find( "table", "class":"nasdaq-screener__table" )
    
    for row in table.findAll("tr"):
        for cell in row("td"):
            data = cell.get_text().strip()
            df = pd.DataFrame(data)
            lst.append(df)
            
    def get_cpf():
        driver = webdriver.Chrome("C:/Utility/chromedriver.exe")
        driver.get(url)
        driver.find_element_by_class('pagination__page" data-page="'' +  numb + ''').click()
        sleep(10)
        text=driver.find_element_by_id('texto_cpf').text
        print(text)
    get_cpf()
    get_cpf.click


### third attempt
from bs4 import BeautifulSoup
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
import time
import requests
import pandas as pd

lst = []

url="https://www.nasdaq.com/market-activity/stocks/screener"
driver = webdriver.Chrome("C:/Utility/chromedriver.exe")
wait = WebDriverWait(driver, 10)
driver.get(url)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#_evh-ric-c"))).click()
for pages in range(1,9):
    try:
        print(pages)
        r = requests.get(url)
        html = r.text
        soup = BeautifulSoup(html, "html.parser")
        table = soup.find_all('table')
        df = pd.DataFrame(table)
        lst.append(df)
        wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button.pagination__next"))).click()
        time.sleep(1)
    except:
        break

这是我试图抓取的表格后面的 HTML 的屏幕截图。

所以,在第一页上,我想从以下位置抓取所有内容:

AAPL    Apple Inc. Common Stock $127.79 6.53    5.385%  2,215,538,678,600

收件人:

ASML    ASML Holding N.V. New York Registry Shares  $583.55 16.46   2.903%  243,056,764,541

然后,移至第 2 页,执行相同操作,移至第 3 页,执行相同操作,等等等等。我不确定仅使用 BeautifulSoup 是否可行。或者也许我需要 Selenium,用于按钮单击事件。我愿意做这里最简单的事情。谢谢!

【问题讨论】:

请检查以下 api 以获取所需的详细信息。 api.nasdaq.com/api/screener/…您可以根据需要设置偏移量,以便从一页移动到另一页。 【参考方案1】:

请注意,您不需要使用 selenium 来执行此类任务,因为它会减慢您的进程。

在实际场景中,我们只使用selenium绕过浏览器检测,然后我们将cookie传递给任何HTTP模块以继续操作。

关于你的任务,我注意到有一个API 实际上是为HTML 提供源。

这是一个快速调用。

import pandas as pd
import requests


def main(url):
    headers = 
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
    

    params = 
        'tableonly': 'true',
        'limit': 1000
    
    r = requests.get(
        'https://api.nasdaq.com/api/screener/stocks', params=params, headers=headers)
    goal = pd.DataFrame(r.json()['data']['table']['rows'])
    print(goal)

    goal.to_csv('data.csv', index=False)


if __name__ == "__main__":
    main('https://api.nasdaq.com/api/screener/stocks')

请注意,每页包含 25 个股票代码。在我的代码中,我获取了1000/ 25 = 40 页。

你不需要在这里循环pages。因为您可以与增加限制进行交互!

但如果你想使用for循环,那么你必须循环以下内容

并保持偏移量。

https://api.nasdaq.com/api/screener/stocks?tableonly=true&limit=25&offset=0

【讨论】:

效果很好。我认为解决方案看起来与此完全不同。为什么这行得通?这是如何工作的?【参考方案2】:

不会处理 API,因为 Nuran 只是按照用户的要求进行处理

以下是浏览前 10 页的示例。首先我们删除通知。然后等待下一个按钮可交互并单击它。

wait = WebDriverWait(driver, 10)
driver.get("https://www.nasdaq.com/market-activity/stocks/screener")
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#_evh-ric-c"))).click()
#Currently you start on the 1st page and say we want to click 9 times for the 10th page
for pages in range(1,10):
    try:
        print(pages)
        #Get your data from this page
        wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button.pagination__next"))).click()
        #This is just here to slow everything so it may be removeable. 
        time.sleep(5)
    except:
        break

导入

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC

你可以这样做

html=driver.page_source
soup=BeautifulSoup(html,'html.parser')
div=soup.select_one("table.nasdaq-screener__table")
table=pd.read_html(str(div))
print(table[0])

【讨论】:

感谢 Arundeep Chohan。我刚试过你的建议。在我更新的帖子中,所有代码都显示在“第三次尝试”下。脚本运行,但它似乎没有做任何事情,它只是运行并且永不停止。想法? ***.com/questions/58347261/…。是获取所有值的简单方法。

以上是关于我们如何导航到一个网页,抓取数据,移动到下一页,然后再做一次?的主要内容,如果未能解决你的问题,请参考以下文章

php命令不会将我移动到下一页

在Objective C中导航到下一页[重复]

延迟导航到下一页

如何使用angularjs变量使超链接移动到下一页?

如何使用 xamarin 表单提高移动设备的性能

如何解决我的提交按钮问题,我无法移动到下一页[重复]