Я использовал скрипт для локального запуска селена, чтобы я мог использовать ответ (полученный из селена) внутри моего паука.
Это веб-сервис, где селен работает локально:
from flask import Flask, request, make_response
from flask_restful import Resource, Api
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
app = Flask(__name__)
api = Api(app)
class Selenium(Resource):
_driver = None
@staticmethod
def getDriver():
if not Selenium._driver:
chrome_options = Options()
chrome_options.add_argument("--headless")
Selenium._driver = webdriver.Chrome(options=chrome_options)
return Selenium._driver
@property
def driver(self):
return Selenium.getDriver()
def get(self):
url = str(request.args['url'])
self.driver.get(url)
return make_response(self.driver.page_source)
api.add_resource(Selenium, '/')
if __name__ == '__main__':
app.run(debug=True)
Это мой скучный паук, который использует этот ответ для анализа заголовка с веб-страницы.
import scrapy
from urllib.parse import quote
from scrapy.crawler import CrawlerProcess
class StackSpider(scrapy.Spider):
name = 'stackoverflow'
url = 'https://stackoverflow.com/questions/tagged/web-scraping?sort=newest&pageSize=50'
base = 'https://stackoverflow.com'
def start_requests(self):
link = 'http://127.0.0.1:5000/?url={}'.format(quote(self.url))
yield scrapy.Request(link,callback=self.parse)
def parse(self, response):
for item in response.css(".summary .question-hyperlink::attr(href)").getall():
nlink = self.base + item
link = 'http://127.0.0.1:5000/?url={}'.format(quote(nlink))
yield scrapy.Request(link,callback=self.parse_info,dont_filter=True)
def parse_info(self, response):
item = response.css('h1[itemprop="name"] > a::text').get()
yield {"title":item}
if __name__ == '__main__':
c = CrawlerProcess()
c.crawl(StackSpider)
c.start()
Проблема в том, что приведенный выше скрипт дает мне один и тот же заголовок несколько раз, затем другой заголовок и т. Д.
Какую возможность я должен вызвать, чтобы мой сценарий работал правильно?