我正在构建一个 SCRAPY SPIDER
,我可以在其中向 API
发送请求。我需要检查一个条件是否满足,我需要打破循环。
我在 parse
方法和内容以及 parse_api
方法中有循环。我尝试使用以下逻辑,但没有奏效。
if 'date container' not in self.html:
break
我收到以下异常 AttributeError: 'SpiderClass' object has no attribute 'html'
处理此异常的可能逻辑是什么?
下面是我的代码:
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.selector import Selector
import json
class SpiderClass(scrapy.Spider):
name = 'spider_name'
custom_settings = {
"FEED_FORMAT": 'csv',
"FEED_URI": 'dataset.csv'
}
def start_requests(self):
links_list = ['https://10times.com/company/informa-knect']
for link in links_list:
yield scrapy.Request(url=link, callback=self.parse)
def parse(self, response):
ids = response.xpath('//input[@id="companyId"]/@value').get()
company_name = response.xpath('//h1/text()').get()
main_data = {
"Links": response.url,
"CompanyName": company_name,
}
# sending request for upcoming event api
off_set = 1
while True:
if 'date-container' not in self.html:
break
off_set_number = off_set * 5
api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set_number}&pastHit=0&calValue=upcoming'
yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)
off_set += 1
def parse_api(self, response):
api_json = json.loads(response.body)
self.html = api_json['html']
if __name__ == '__main__':
process = CrawlerProcess()
process.crawl(SpiderClass)
process.start()
答案 0 :(得分:1)
所以,您的代码中还有一些其他问题。您使用值 ids
但这并未在任何地方定义。您需要以某种方式生成它。
另外,在 yield
语句之前需要有一个初始的 while
。没抓住这个是我的错。问题是,如果没有初始的 yield
,hasattr(self, 'html')
的评估将始终为 False
。
def parse(self, response):
company_name = response.xpath('//h1/text()').get()
main_data = {
"Links": response.url,
"CompanyName": company_name,
}
# sending request for upcoming event api
off_set = 1
api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set * 5}&pastHit=0&calValue=upcoming'
yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)
while hasattr(self, 'html') and 'date-container' in self.html:
off_set_number = off_set * 5
api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set_number}&pastHit=0&calValue=upcoming'
yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)
off_set += 1
有两点,使用 while True
后跟 if
语句绝对不是要走的路。 while
语句已经是评估语句。 See w3schools。
其次,standard function hasattr()
将检查对象是否具有列出的属性。如果不是,它将返回 False
并且不执行评估的第二部分。
def parse(self, response):
company_name = response.xpath('//h1/text()').get()
main_data = {
"Links": response.url,
"CompanyName": company_name,
}
# sending request for upcoming event api
off_set = 1
# the while statement already does an if.
while hasattr(self, 'html') and 'date-container' in self.html:
off_set_number = off_set * 5
api_url = f'https://10times.com/ajax?for=companyEvents&id={ids}&by=&offset={off_set_number}&pastHit=0&calValue=upcoming'
yield response.follow(url=api_url, meta=main_data,callback=self.parse_api)
off_set += 1