使用 Scrapy 规则对 URL 列表中的参数进行爬网迭代
Crawl iterating with a parameter over a list of urls from a rule with Scrapy
我是 Scrapy 和 Python 的新手。我想执行以下操作:
访问url并获取所有links 包含"shop/products"作为[=的一部分76=]。 link 看起来像:“http://www.example.com/shop/products/category-name”
舍弃 start_urls 的 url,得到总产品数,TOTAL。在代码上 TOTAL = num_items_per_category.
最后,将"?sort=Top&size=12&start=PARAM"添加到url. PARAM 必须在每次迭代时递增 12,以防 PARAM <= TOTAL。最后的 url 将是“http://www.example.com/shop/products/category-name?sort=Top&size=12&start=PARAM”
从生成的start_urls中获取另一个url并重新开始第2步。
这是我的爬虫代码:
import scrapy
import re
import datetime
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from scrapy.http.request import Request
class MySpider(CrawlSpider):
name = 'my_spider'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com/shop/products']
rules = (
Rule(LxmlLinkExtractor(
restrict_xpaths=('.//li[@class="item"]/a')),
follow=False,
callback='parse_list'
),
)
def parse_list(self, response):
SET_SELECTOR = '.product'
for item in response.css(ITEM_SELECTOR):
NAME_SELECTOR = 'div[@class="product"]/h2/a/@title'
yield {
'name': item.xpath(NAME_SELECTOR).extract_first()
}
NUM_ITEMS_PER_CATEGORY_SELECTOR = 'div[@id="search"]/@data-count'
num_items_per_category = item.xpath(NUM_ITEMS_PER_CATEGORY_SELECTOR).extract_first()
nipc = int(0 if num_items_per_category is None else num_items_per_category)
try:
next_start = response.meta["next_start"]
except KeyError:
next_start = 0
if next_start <= nipc:
yield scrapy.Request(
response.urljoin('%s?sort=Top&size=12&start=%s' % (response.url, next_start)),
meta={"next_start": next_start + 12},
dont_filter=True,
callback = self.parse_list
)
问题是:
我不知道它是否存在任何 css select 或正则表达式用于 select 每个 link 我想。在代码上,我访问的路径我知道有一些我想要的 link,但页面上还有更多。
代码未按预期运行。似乎 next_start 没有在每次迭代中递增 12。该代码仅获取生成的 start_urls 列表中每个 url 的前 12 个元素。我是否正确使用了 meta 变量?或者我可能需要每个类别页面的另一个第一个片段来获得总计数,然后才能使用它来迭代它?或者,也许我需要另一种使用 start_requests 的方法...你怎么看?
你的蜘蛛所做的就是访问 url http://www.example.com/shop/products
,提取 <li class="item">
元素内的所有链接并使用 parse_list
回调获取所有链接。正如我所见,这不是您正在等待的行为 - 相反,您应该使用一些开始 url 包含种子 URLs 和 Extractor with allow=r"shop/products"
在规则中。
这部分 '%s?sort=Top&size=12&start=%s' % (response.url, next_start)
也是错误的,因为 response.url 包含完整的 URL,包括 GET 参数,因此每次您将带有参数的部分附加到现有参数字符串时,就像这样 ?sort=Top&size=12&start=0?sort=Top&size=12&start=12?sort=Top&size=12&start=24
.在附加新字符串之前清除 url 中的参数,或者只使用 FormRequest
作为传递参数的更方便的方式。
顺便说一句,Scrapy 有非常方便的交互式控制台用于调试目的,您可以使用 scrapy.shell.inspect_response
.
从 spider 的任何部分调用它
我是 Scrapy 和 Python 的新手。我想执行以下操作:
访问url并获取所有links 包含"shop/products"作为[=的一部分76=]。 link 看起来像:“http://www.example.com/shop/products/category-name”
舍弃 start_urls 的 url,得到总产品数,TOTAL。在代码上 TOTAL = num_items_per_category.
最后,将"?sort=Top&size=12&start=PARAM"添加到url. PARAM 必须在每次迭代时递增 12,以防 PARAM <= TOTAL。最后的 url 将是“http://www.example.com/shop/products/category-name?sort=Top&size=12&start=PARAM”
从生成的start_urls中获取另一个url并重新开始第2步。
这是我的爬虫代码:
import scrapy
import re
import datetime
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from scrapy.http.request import Request
class MySpider(CrawlSpider):
name = 'my_spider'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com/shop/products']
rules = (
Rule(LxmlLinkExtractor(
restrict_xpaths=('.//li[@class="item"]/a')),
follow=False,
callback='parse_list'
),
)
def parse_list(self, response):
SET_SELECTOR = '.product'
for item in response.css(ITEM_SELECTOR):
NAME_SELECTOR = 'div[@class="product"]/h2/a/@title'
yield {
'name': item.xpath(NAME_SELECTOR).extract_first()
}
NUM_ITEMS_PER_CATEGORY_SELECTOR = 'div[@id="search"]/@data-count'
num_items_per_category = item.xpath(NUM_ITEMS_PER_CATEGORY_SELECTOR).extract_first()
nipc = int(0 if num_items_per_category is None else num_items_per_category)
try:
next_start = response.meta["next_start"]
except KeyError:
next_start = 0
if next_start <= nipc:
yield scrapy.Request(
response.urljoin('%s?sort=Top&size=12&start=%s' % (response.url, next_start)),
meta={"next_start": next_start + 12},
dont_filter=True,
callback = self.parse_list
)
问题是:
我不知道它是否存在任何 css select 或正则表达式用于 select 每个 link 我想。在代码上,我访问的路径我知道有一些我想要的 link,但页面上还有更多。
代码未按预期运行。似乎 next_start 没有在每次迭代中递增 12。该代码仅获取生成的 start_urls 列表中每个 url 的前 12 个元素。我是否正确使用了 meta 变量?或者我可能需要每个类别页面的另一个第一个片段来获得总计数,然后才能使用它来迭代它?或者,也许我需要另一种使用 start_requests 的方法...你怎么看?
你的蜘蛛所做的就是访问 url http://www.example.com/shop/products
,提取 <li class="item">
元素内的所有链接并使用 parse_list
回调获取所有链接。正如我所见,这不是您正在等待的行为 - 相反,您应该使用一些开始 url 包含种子 URLs 和 Extractor with allow=r"shop/products"
在规则中。
这部分 '%s?sort=Top&size=12&start=%s' % (response.url, next_start)
也是错误的,因为 response.url 包含完整的 URL,包括 GET 参数,因此每次您将带有参数的部分附加到现有参数字符串时,就像这样 ?sort=Top&size=12&start=0?sort=Top&size=12&start=12?sort=Top&size=12&start=24
.在附加新字符串之前清除 url 中的参数,或者只使用 FormRequest
作为传递参数的更方便的方式。
顺便说一句,Scrapy 有非常方便的交互式控制台用于调试目的,您可以使用 scrapy.shell.inspect_response
.