我们如何导航到一个网页,抓取数据,移动到下一页,然后再做一次?
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/…。是获取所有值的简单方法。以上是关于我们如何导航到一个网页,抓取数据,移动到下一页,然后再做一次?的主要内容,如果未能解决你的问题,请参考以下文章