Python 使用Scrapy模拟AJAX请求以收集分页数据
我正在做一个小项目,从一个流行的传奇联盟网站www.op.gg收集一些数据。例如,如果您转到第页,您将看到右侧显示了价值10场比赛的数据。如果你一直向下滚动,你会在底部看到接下来的20个结果,以此类推。当我使用chrome工具检查“Show More”元素时,我看到以下条目:Python 使用Scrapy模拟AJAX请求以收集分页数据,python,python-3.x,scrapy,data-science,Python,Python 3.x,Scrapy,Data Science,我正在做一个小项目,从一个流行的传奇联盟网站www.op.gg收集一些数据。例如,如果您转到第页,您将看到右侧显示了价值10场比赛的数据。如果你一直向下滚动,你会在底部看到接下来的20个结果,以此类推。当我使用chrome工具检查“Show More”元素时,我看到以下条目: <a href="#" onclick="$.OP.GG.matches.list.loadMore($(this)); return false;" class="Button">Show More</
<a href="#" onclick="$.OP.GG.matches.list.loadMore($(this)); return false;" class="Button">Show More</a>
仅使用
Selenium
您只需单击按钮即可。使用其他工具,您可以在DevTools(在tab Network中)中检查当您单击按钮(特别是XHR请求)时它发送的请求并使用它-也许它可以在不模拟AJAX的情况下工作,您可以获得JSON数据,这些数据可以轻松地转换为Python的列表/字典。要模拟AJAX,当我使用网络选项卡并单击“显示更多”时,必须添加一个标题XMLHttpRequest
,这样会出现类似的链接。这是一个HTML字符串的JSON——你知道用我能从Scrapy中解析CSS的同样方法来解析它的最有效方法吗?你可以使用lxml
或Beautifulsoup
来解析它,并使用gnCSS
或xpath
进行搜索。或者您可以使用Scrapy和HtmlResponse
或Selector
从字符串/HTML创建响应-请参阅您是否尝试将此HTML直接与HtmlResponse
、Selector
、BeautifulSoup
或lmxl
一起使用。它们不需要完整的HTML即可工作。从Scrapy导入选择器数据=Selector(text=string)data.css('#myid::text').get()
import scrapy
class PostsSpider(scrapy.Spider):
name = "posts"
start_urls = [
'https://na.op.gg/summoner/userName=C9+Zven',
'https://na.op.gg/summoner/userName=From+Iron'
]
def parse(self, response):
summoner_name = response.css('.SummonerLayout>.Header>.Profile>.Information>.Name::text').get()
rank_type = response.css('.TierRankInfo .RankType::text').get()
tier_rank = response.css('.TierRankInfo .TierRank::text').get()
game_lists = []
dict_per_game = {}
for game in response.css('div.GameItemWrap'):
dict_per_game['summoner_id'] = game.css('.GameItem::attr(data-summoner-id)').get()
dict_per_game['data_game_time'] = game.css('.GameItem::attr(data-game-time)').get()
dict_per_game['game_type'] = str.strip(game.css('.Content .GameStats .GameType::text').get())
dict_per_game['date_time_epoch'] = game.css('.Content .GameStats .TimeStamp ._timeago::attr(data-datetime)').get()
dict_per_game['game_result'] = str.strip(game.css('.Content .GameStats .GameResult::text').get())
dict_per_game['champ_name'] = game.css('.Content .GameSettingInfo .ChampionName a::text').get()
dict_per_game['kill'] = game.css('.Content .KDA .KDA .Kill::text').get()
dict_per_game['death'] = game.css('.Content .KDA .KDA .Death::text').get()
dict_per_game['assist'] = game.css('.Content .KDA .KDA .Assist::text').get()
game_lists.append(dict_per_game)
dict_per_game = {}
yield {
'summoner_name': summoner_name,
'rank_type': rank_type,
'tier_rank': tier_rank,
'games': game_lists
}
# This is where I would like to add some code to retrieve more results for this profile going back to 30 days ago from runtime