Python 让刮毛蜘蛛按顺序爬到最深处
我正试图让一个脏兮兮的蜘蛛按照蜘蛛代码发出Request()调用的顺序来抓取网站的页面 类似于这个问题: 我检查了这个问题的答案,并尝试了一下,但没有一个能完全符合我的要求 我的问题是我需要在一页上刮一张桌子。每个表都有一个,其中一个值是指向另一页的href。第一个回调方法刮取表,然后使用href对另一个页面进行后续Request()调用。第一个页面将调用许多其他页面。我使用meta关键字将dict中第一个回调方法的数据传递给第二个回调方法 第二个回调方法刮取该页的内容,并将解析后的数据添加到传递给的dict中。但是第一次回调的数据并不总是与第二次回调的数据用于同一个游戏 第一页的XML文档如下所示:Python 让刮毛蜘蛛按顺序爬到最深处,python,scrapy,Python,Scrapy,我正试图让一个脏兮兮的蜘蛛按照蜘蛛代码发出Request()调用的顺序来抓取网站的页面 类似于这个问题: 我检查了这个问题的答案,并尝试了一下,但没有一个能完全符合我的要求 我的问题是我需要在一页上刮一张桌子。每个表都有一个,其中一个值是指向另一页的href。第一个回调方法刮取表,然后使用href对另一个页面进行后续Request()调用。第一个页面将调用许多其他页面。我使用meta关键字将dict中第一个回调方法的数据传递给第二个回调方法 第二个回调方法刮取该页的内容,并将解析后的数据添加到传
# Game Schedule page
<html>
<body>
<div>
<table type="games">
<tbody>
<tr row="1">
<th data="week_number">1</th>
<td data="date">"9/13/2020"</td>
<td data="game_id">1</td>
<td data="game_summary"><a href="/game/20200913_01.html">game stats</a></td>
</tr>
<tr row="2">
<th data="week_number">1</th>
<td data="date">"9/13/2020"</td>
<td data="game_id">2</td>
<td data="game_summary"><a href="/game/20200913_02.html">game stats</a></td>
</tr>
<tr row="3">
<th data="week_number">1</th>
<td data="date">"9/13/2020"</td>
<td data="game_id">3</td>
<td data="game_summary"><a href="/game/20200913_03.html">game stats</a></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
回调方法“parse_schedule_summary_page”解析来自游戏时间表页面的s,包括每个游戏的游戏统计摘要页面的URL
它发出一个“yield Request()”调用,Request()参数的一部分是游戏目录,使用“meta”关键字
从self.log(stmt)语句的输出中,我注意到game_id条目和x_game_id条目在以下情况下并不相同:
==**==**==**==
{'v_team': 'Team A', 'game_time': '6:30PM','game_id': '1', 'h_team_score': '53',
'h_team': 'Team B', 'week_num': '1', 'date': '9/13/2020', 'x_game_id': '7', 'v_team_score': '43'}
**==**==**==**
parse_schedule_summary_page()中的游戏id与parse_game_page()中的x_游戏id不匹配。大多数比赛都是这样,但不是所有比赛都是这样
提到前面的问题,这是因为Scrapy无法确保URL的顺序
根据其建议,我首先在我的settings.py文件中更改了此配置:
# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 1
这没用;当我使用此选项设置运行游戏时,游戏数据仍然不同步
我尝试在parse_schedule_summary_page()中设置请求()的优先级,但这也没有解决问题
因此,我尝试了另一个建议并更改了此代码:
yield Request(summary_url, priority=5, meta={'dict': game_dict},\
callback=self.parse_game_page)
为此:
return [Request(summary_url, priority=5, meta={'dict': game_dict},\
callback=self.parse_game_page)]
通过不使用yield命令,游戏日程页面中的游戏信息与游戏统计摘要页面中的数据保持同步。但是,卡盘仅在处理一个卡盘后结束
我如何在parse_schedule_summary_page()中调用Request()调用,调用条目中的每个HREF并刮取每个游戏统计摘要页面,而不是在处理一个页面后停止?另一种方法
from simplified_scrapy import Spider, SimplifiedDoc, SimplifiedMain, utils
class MySpider(Spider):
name = 'my_spider'
start_urls = ['https://somewebsite.com/2019.GameSchedule.htm']
# refresh_urls = True # If you want to download the downloaded link again, please remove the "#" in the front
def extract(self, url, html, models, modelNames):
doc = SimplifiedDoc(html)
lstA = []
game_dict = {}
if url.url in self.start_urls:
# Get all rows
trs = doc.getElement('table', attr='type', value='games').trs
for tr in trs:
cols = tr.children
url = {
'url': utils.absoluteUrl(url.url, tr.a.href)
} # Splicing URL full path
for col in cols:
url[col['data']] = col.text # Pass data to the next page
lstA.append(url)
else:
cols = doc.getElement('table', attr='type',
value='game stat').tr.tds
for col in cols:
game_dict[col['data']] = col.text
game_dict['week_number'] = url[
'week_number'] # Use the data from the previous page
game_dict['game_summary'] = url['game_summary']
return {
'Urls': lstA, 'Data': game_dict
} # Return the data to the framework, which will save it for you.
SimplifiedMain.startThread(MySpider()) # Start download
这里有更多的例子:另一种方法
from simplified_scrapy import Spider, SimplifiedDoc, SimplifiedMain, utils
class MySpider(Spider):
name = 'my_spider'
start_urls = ['https://somewebsite.com/2019.GameSchedule.htm']
# refresh_urls = True # If you want to download the downloaded link again, please remove the "#" in the front
def extract(self, url, html, models, modelNames):
doc = SimplifiedDoc(html)
lstA = []
game_dict = {}
if url.url in self.start_urls:
# Get all rows
trs = doc.getElement('table', attr='type', value='games').trs
for tr in trs:
cols = tr.children
url = {
'url': utils.absoluteUrl(url.url, tr.a.href)
} # Splicing URL full path
for col in cols:
url[col['data']] = col.text # Pass data to the next page
lstA.append(url)
else:
cols = doc.getElement('table', attr='type',
value='game stat').tr.tds
for col in cols:
game_dict[col['data']] = col.text
game_dict['week_number'] = url[
'week_number'] # Use the data from the previous page
game_dict['game_summary'] = url['game_summary']
return {
'Urls': lstA, 'Data': game_dict
} # Return the data to the framework, which will save it for you.
SimplifiedMain.startThread(MySpider()) # Start download
这里有更多的例子:我尝试了不同的方法来解决这个问题。但它们都不起作用。唯一的方法似乎是不为parse_game_页面单独回调,而是使用scrapy_inline_请求模块。有人有其他选择或想法吗?我只是猜测,但另一种方法是在我的蜘蛛中使用BeautifulSoup。但这似乎太不公平了。我尝试了不同的方法来解决这个问题。但它们都不起作用。唯一的方法似乎是不为parse_game_页面单独回调,而是使用scrapy_inline_请求模块。有人有其他选择或想法吗?我只是猜测,但另一种方法是在我的蜘蛛中使用BeautifulSoup。但这似乎太不公平了。达宾寿:我用pip安装了简化的scrapy。它是1.3.146版。我在Python2.7.5上使用它。当我尝试时,我得到一个ImportError:from simplified_scrapy import SimplifiedMain“from queue import queue ImportError:No module named queue”我检查了GitHub站点的simplified scrapy,没有看到任何使用此包的预请求。有没有需要使用simplified_scrapy的pip包?@SQA777可以将Python升级到2.7.15吗?我可以用这个版本运行它。与其将我的Python升级到2.7.15,安装包含队列模块的包不是更容易吗?@SQA777你说得对。或者您可以升级simplified scrapy library.Dabinsou:有队列模块的包是什么(对于Python 2.7.5)?Dabinsou:我使用pip安装了simplified scrapy。它是1.3.146版。我在Python2.7.5上使用它。当我尝试时,我得到一个ImportError:from simplified_scrapy import SimplifiedMain“from queue import queue ImportError:No module named queue”我检查了GitHub站点的simplified scrapy,没有看到任何使用此包的预请求。有没有需要使用simplified_scrapy的pip包?@SQA777可以将Python升级到2.7.15吗?我可以用这个版本运行它。与其将我的Python升级到2.7.15,安装包含队列模块的包不是更容易吗?@SQA777你说得对。或者您可以升级简化的scrapy库。Dabinsou:什么是包含队列模块的包(对于Python 2.7.5)?
yield Request(summary_url, priority=5, meta={'dict': game_dict},\
callback=self.parse_game_page)
return [Request(summary_url, priority=5, meta={'dict': game_dict},\
callback=self.parse_game_page)]
from simplified_scrapy import Spider, SimplifiedDoc, SimplifiedMain, utils
class MySpider(Spider):
name = 'my_spider'
start_urls = ['https://somewebsite.com/2019.GameSchedule.htm']
# refresh_urls = True # If you want to download the downloaded link again, please remove the "#" in the front
def extract(self, url, html, models, modelNames):
doc = SimplifiedDoc(html)
lstA = []
game_dict = {}
if url.url in self.start_urls:
# Get all rows
trs = doc.getElement('table', attr='type', value='games').trs
for tr in trs:
cols = tr.children
url = {
'url': utils.absoluteUrl(url.url, tr.a.href)
} # Splicing URL full path
for col in cols:
url[col['data']] = col.text # Pass data to the next page
lstA.append(url)
else:
cols = doc.getElement('table', attr='type',
value='game stat').tr.tds
for col in cols:
game_dict[col['data']] = col.text
game_dict['week_number'] = url[
'week_number'] # Use the data from the previous page
game_dict['game_summary'] = url['game_summary']
return {
'Urls': lstA, 'Data': game_dict
} # Return the data to the framework, which will save it for you.
SimplifiedMain.startThread(MySpider()) # Start download