使用 Infinite Scroll 从网站抓取数据?
Scraping data from a website with Infinite Scroll?
我正在尝试抓取网站上的标题和其他项目,但为了简洁起见,只抓取游戏标题。
我试过同时使用 selenium 和 beautiful soup 来获取标题,但无论我做什么,我似乎都无法获取所有 9 月发布的内容。事实上,我也获得了一些八月份的游戏称号。我认为这与网站没有结尾这一事实有关。我怎样才能只抢到 9 月的冠军头衔?下面是我使用的代码,我尝试使用 Scrolling,但我认为我不明白如何正确使用它。
编辑:我的目标是能够通过更改几行代码最终获得每个月。
from selenium import webdriver
from bs4 import BeautifulSoup
titles = []
chromedriver = 'C:/Users/Chase The Great/Desktop/Podcast/chromedriver.exe'
driver = webdriver.Chrome(chromedriver)
driver.get('https://www.releases.com/l/Games/2019/9/')
res = driver.execute_script("return document.documentElement.outerHTML")
driver.quit()
soup = BeautifulSoup(res, 'lxml')
for title in soup.find_all(class_= 'calendar-item-title'):
titles.append(title.text)
我预计将获得 133 个标题,我获得了一些 8 月的标题加上仅部分标题:
['SubaraCity', 'AER - Memories of Old', 'Vambrace: Cold Soul', 'Agent A: A Puzzle in Disguise', 'Bubsy: Paws on Fire!', 'Grand Brix Shooter', 'Legend of the Skyfish', 'Vambrace: Cold Soul', 'Obakeidoro!', 'Pokemon Masters', 'Decay of Logos', 'The Lord of the Rings: Adventure ...', 'Heave Ho', 'Newt One', 'Blair Witch', 'Bulletstorm: Duke of Switch Edition', 'The Ninja Saviors: Return of the ...', 'Re:Legend', 'Risk of Rain 2', 'Decay of Logos', 'Unlucky Seven', 'The Dark Pictures Anthology: Man ...', 'Legend of the Skyfish', 'Astral Chain', 'Torchlight II', 'Final Fantasy VIII Remastered', 'Catherine: Full Body', 'Root Letter: Last Answer', 'Children of Morta', 'Himno', 'Spyro Reignited Trilogy', 'RemiLore: Lost Girl in the Lands ...', 'Divinity: Original Sin 2 - Defini...', 'Monochrome Order', 'Throne Quest Deluxe', 'Super Kirby Clash', 'Himno', 'Post War Dreams', 'The Long Journey Home', 'Spice and Wolf VR', 'WRC 8', 'Fantasy General II', 'River City Girls', 'Headliner: NoviNews', 'Green Hell', 'Hyperforma', 'Atomicrops', 'Remothered: Tormented Fathers']
在我看来,为了只获取 9 月,首先你只想获取 9 月的部分:
section = soup.find('section', {'class': 'Y2019-M9 calendar-sections'})
然后,一旦您获取了 9 月的部分,就可以获取 <a>
标签中的所有标题,如下所示:
for title in section.find_all('a', {'class': ' calendar-item-title subpage-trigg'}):
titles.append(title.text)
请注意,之前的none已经过测试。
更新:
问题是每次你想加载页面时,它只给你第一个部分,只包含 24 个项目,为了访问它们你必须向下滚动(无限滚动)。
如果您打开浏览器开发人员工具,select Network
然后 XHR
您会注意到每次滚动并加载下一个 "page" 时都会有一个带有 url
类似于:
https://www.releases.com/calendar/nextAfter?blockIndex=139&itemIndex=23&category=Games®ionId=us
我的猜测是 blockIndex
表示月份,itemIndex
表示每个加载的页面,如果您只查找 9 月 blockIndex
将始终139
在该请求中,挑战是获取下一页的下一个 itemIndex
,以便您可以构建下一个请求。
下一个 itemIndex
将始终是上一个请求的最后一个 itemIndex
。
我确实制作了一个脚本,仅使用 BeautifulSoup
即可执行您想要的操作。请自行决定使用它,有些常量可能会动态提取,但我认为这可以让您抢先一步:
import json
import requests
from bs4 import BeautifulSoup
DATE_CODE = 'Y2019-M9'
LAST_ITEM_FIRST_PAGE = f'calendar-item col-xs-6 to-append first-item calendar-last-item {DATE_CODE}-None'
LAST_ITEM_PAGES = f'calendar-item col-xs-6 to-append calendar-last-item {DATE_CODE}-None'
INITIAL_LINK = 'https://www.releases.com/l/Games/2019/9/'
BLOCK = 139
titles = []
def get_next_page_link(div: BeautifulSoup):
index = div['item-index']
return f'https://www.releases.com/calendar/nextAfter?blockIndex={BLOCK}&itemIndex={index}&category=Games®ionId=us'
def get_content_from_requests(page_link):
headers = requests.utils.default_headers()
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
req = requests.get(page_link, headers=headers)
return BeautifulSoup(req.content, 'html.parser')
def scroll_pages(link: str):
print(link)
page = get_content_from_requests(link)
for div in page.findAll('div', {'date-code': DATE_CODE}):
item = div.find('a', {'class': 'calendar-item-title subpage-trigg'})
if item:
# print(f'TITLE: {item.getText()}')
titles.append(item.getText())
last_index_div = page.find('div', {'class': LAST_ITEM_FIRST_PAGE})
if not last_index_div:
last_index_div = page.find('div', {'class': LAST_ITEM_PAGES})
if last_index_div:
scroll_pages(get_next_page_link(last_index_div))
else:
print(f'Found: {len(titles)} Titles')
print('No more pages to scroll finishing...')
scroll_pages(INITIAL_LINK)
with open(f'titles.json', 'w') as outfile:
json.dump(titles, outfile)
如果您的目标是使用 Selenium
,我认为同样的原则可能适用,除非它在加载页面时具有滚动功能。
相应地替换 INITIAL_LINK
、DATE_CODE
和 BLOCK
,您也会得到其他月份。
我正在尝试抓取网站上的标题和其他项目,但为了简洁起见,只抓取游戏标题。
我试过同时使用 selenium 和 beautiful soup 来获取标题,但无论我做什么,我似乎都无法获取所有 9 月发布的内容。事实上,我也获得了一些八月份的游戏称号。我认为这与网站没有结尾这一事实有关。我怎样才能只抢到 9 月的冠军头衔?下面是我使用的代码,我尝试使用 Scrolling,但我认为我不明白如何正确使用它。
编辑:我的目标是能够通过更改几行代码最终获得每个月。
from selenium import webdriver
from bs4 import BeautifulSoup
titles = []
chromedriver = 'C:/Users/Chase The Great/Desktop/Podcast/chromedriver.exe'
driver = webdriver.Chrome(chromedriver)
driver.get('https://www.releases.com/l/Games/2019/9/')
res = driver.execute_script("return document.documentElement.outerHTML")
driver.quit()
soup = BeautifulSoup(res, 'lxml')
for title in soup.find_all(class_= 'calendar-item-title'):
titles.append(title.text)
我预计将获得 133 个标题,我获得了一些 8 月的标题加上仅部分标题:
['SubaraCity', 'AER - Memories of Old', 'Vambrace: Cold Soul', 'Agent A: A Puzzle in Disguise', 'Bubsy: Paws on Fire!', 'Grand Brix Shooter', 'Legend of the Skyfish', 'Vambrace: Cold Soul', 'Obakeidoro!', 'Pokemon Masters', 'Decay of Logos', 'The Lord of the Rings: Adventure ...', 'Heave Ho', 'Newt One', 'Blair Witch', 'Bulletstorm: Duke of Switch Edition', 'The Ninja Saviors: Return of the ...', 'Re:Legend', 'Risk of Rain 2', 'Decay of Logos', 'Unlucky Seven', 'The Dark Pictures Anthology: Man ...', 'Legend of the Skyfish', 'Astral Chain', 'Torchlight II', 'Final Fantasy VIII Remastered', 'Catherine: Full Body', 'Root Letter: Last Answer', 'Children of Morta', 'Himno', 'Spyro Reignited Trilogy', 'RemiLore: Lost Girl in the Lands ...', 'Divinity: Original Sin 2 - Defini...', 'Monochrome Order', 'Throne Quest Deluxe', 'Super Kirby Clash', 'Himno', 'Post War Dreams', 'The Long Journey Home', 'Spice and Wolf VR', 'WRC 8', 'Fantasy General II', 'River City Girls', 'Headliner: NoviNews', 'Green Hell', 'Hyperforma', 'Atomicrops', 'Remothered: Tormented Fathers']
在我看来,为了只获取 9 月,首先你只想获取 9 月的部分:
section = soup.find('section', {'class': 'Y2019-M9 calendar-sections'})
然后,一旦您获取了 9 月的部分,就可以获取 <a>
标签中的所有标题,如下所示:
for title in section.find_all('a', {'class': ' calendar-item-title subpage-trigg'}):
titles.append(title.text)
请注意,之前的none已经过测试。
更新:
问题是每次你想加载页面时,它只给你第一个部分,只包含 24 个项目,为了访问它们你必须向下滚动(无限滚动)。
如果您打开浏览器开发人员工具,select Network
然后 XHR
您会注意到每次滚动并加载下一个 "page" 时都会有一个带有 url
类似于:
https://www.releases.com/calendar/nextAfter?blockIndex=139&itemIndex=23&category=Games®ionId=us
我的猜测是 blockIndex
表示月份,itemIndex
表示每个加载的页面,如果您只查找 9 月 blockIndex
将始终139
在该请求中,挑战是获取下一页的下一个 itemIndex
,以便您可以构建下一个请求。
下一个 itemIndex
将始终是上一个请求的最后一个 itemIndex
。
我确实制作了一个脚本,仅使用 BeautifulSoup
即可执行您想要的操作。请自行决定使用它,有些常量可能会动态提取,但我认为这可以让您抢先一步:
import json
import requests
from bs4 import BeautifulSoup
DATE_CODE = 'Y2019-M9'
LAST_ITEM_FIRST_PAGE = f'calendar-item col-xs-6 to-append first-item calendar-last-item {DATE_CODE}-None'
LAST_ITEM_PAGES = f'calendar-item col-xs-6 to-append calendar-last-item {DATE_CODE}-None'
INITIAL_LINK = 'https://www.releases.com/l/Games/2019/9/'
BLOCK = 139
titles = []
def get_next_page_link(div: BeautifulSoup):
index = div['item-index']
return f'https://www.releases.com/calendar/nextAfter?blockIndex={BLOCK}&itemIndex={index}&category=Games®ionId=us'
def get_content_from_requests(page_link):
headers = requests.utils.default_headers()
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
req = requests.get(page_link, headers=headers)
return BeautifulSoup(req.content, 'html.parser')
def scroll_pages(link: str):
print(link)
page = get_content_from_requests(link)
for div in page.findAll('div', {'date-code': DATE_CODE}):
item = div.find('a', {'class': 'calendar-item-title subpage-trigg'})
if item:
# print(f'TITLE: {item.getText()}')
titles.append(item.getText())
last_index_div = page.find('div', {'class': LAST_ITEM_FIRST_PAGE})
if not last_index_div:
last_index_div = page.find('div', {'class': LAST_ITEM_PAGES})
if last_index_div:
scroll_pages(get_next_page_link(last_index_div))
else:
print(f'Found: {len(titles)} Titles')
print('No more pages to scroll finishing...')
scroll_pages(INITIAL_LINK)
with open(f'titles.json', 'w') as outfile:
json.dump(titles, outfile)
如果您的目标是使用 Selenium
,我认为同样的原则可能适用,除非它在加载页面时具有滚动功能。
相应地替换 INITIAL_LINK
、DATE_CODE
和 BLOCK
,您也会得到其他月份。