Мне нужно решить две проблемы:
Первая: правильно определить местонахождение элемента на веб-сайте с помощью драйвера. Второе: передайте ссылку, созданную в результате этого действия, в метод синтаксического анализа или LinkExtractor.
ad. 1.
Мне нужно найти кнопку «Загрузить еще» и щелкнуть по ней, чтобы просканировать получившуюся страницу.
<div class="col-sm-4 col-sm-offset-4 col-md-2 col-md-offset-5 col-xs-12 col-xs-offset-0">
<button class="btn btn-secondary">Load more</button>
</div>
ad.2.
Я определил LinkExtractor правила, которые корректно работают на сайтах stati c, и метод синтаксического анализа. Я видел много других примеров в подобных вопросах, но не могу понять, как мне их склеить?
Это моя последняя попытка:
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from os.path import join as path_join
import json
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
import time
class MySpider(CrawlSpider):
input_dir = '../input'
encoding = 'utf8'
passing_file = path_join(input_dir, 'site_to_scrap.txt')
with open(passing_file, 'r', encoding = encoding) as f:
input_file = str(f.readlines()[0]).replace('\n', '')
f.close()
with open(path_join(input_dir, input_file + '.json'), 'r') as json_file:
data = json.load(json_file)
json_file.close()
name = data['name']
allowed_domains = data['allowed_domains']
start_urls = data['start_urls']
rules = (
Rule(LinkExtractor(allow=data['allow'], deny=data['deny'],
deny_domains=data['deny_domains'],
restrict_text=data['restrict_text']),
callback='parse_page', follow=True),
)
driver = webdriver.Chrome(ChromeDriverManager().install())
def parse_page(self, response):
self.driver.get(response.url)
self.driver.implicitly_wait(2)
self.driver.find_element_by_class_name('btn btn-secondary').click()
time.sleep(2)
for p in response.css('p'):
yield {
'p': p.css('p::text').get(),
}
for div in response.css('div'):
yield {
'div': div.css('div::text').get(),
}
for title in response.css('div.title'):
yield {
'header': title.css('div.title::text').get(),
}
for head in response.css('head'):
yield {
'header': head.css('head::text').get(),
}
# write visited urls into a file
output_dir = './output'
file = 'visited_urls.txt'
with open(path_join(output_dir, file), 'a') as outfile:
print(response.url, file=outfile)
outfile.close()
Я удалил значительные часть метода parse_page для удобства чтения (это не влияет на выполнение).
Другой пример, который я безуспешно опробовал:
driver = webdriver.Chrome(ChromeDriverManager().install())
def parse_url(self, response):
self.driver.get(response.url)
while True:
self.driver.implicitly_wait(2)
next = self.driver.find_element_by_class_name('btn btn-secondary')
try:
next.click()
time.sleep(2)
# get the data and write it to scrapy items
except:
break
self.driver.close()
Любой намек на один из двух вопросов будет очень признателен.