Хорошо, поэтому проблема с моим сценарием селен была в том, что сценарий завершился до загрузки страницы. Я добавил driver.implicitly_wait(15)
, прежде чем пытаться найти элементы ввода и войти в систему, и это решило эту проблему.
Вот полный код моего рабочего паука:
import scrapy
from scrapy.spiders.init import InitSpider
from scrapy.http import Request
from scrapy.selector import Selector
import selenium
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
#Provide domain, so the spider does not follow external links
DOMAIN = 'test.org'
URL = 'http://%s' % DOMAIN
class HybridSpider(InitSpider):
name = 'hybrid_spider'
allowed_domains = [DOMAIN]
start_urls = [URL]
url_array = []
def init_request(self):
#Provide site information
username = 'email@dummy.com'
password = 'test1234'
login_url = 'https://authentication.test.org/login/'
start_crawling_url = 'https://www.test.org'
#Set path to your chromedriver.exe here.
driver = webdriver.Chrome('C:/Users/somepath/chromedriver.exe')
driver.get(login_url)
driver.implicitly_wait(15)
#If the input field has an id, use it to find the correct field
driver.find_element_by_id('tbUsername').send_keys(username)
driver.find_element_by_id('tbPassword').send_keys(password, Keys.ENTER)
#If it doesn't, get all input fields from the page and tell Selenium to use the n-th one
#driver.find_element(By.XPATH, '//input[1]').send_keys(username)
#driver.find_element(By.XPATH, '//input[last()]').send_keys(password, Keys.ENTER)
driver.implicitly_wait(15)
yield Request(start_crawling_url, cookies=driver.get_cookies(), callback=self.parse, headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0'})
def parse(self, response):
hxs = Selector(response)
filename = 'urls.txt'
for url in hxs.xpath('//a/@href').extract():
if ((url.startswith('http://') or url.startswith('https://') or url.startswith('/')) and not (url.endswith('.pdf') or url.endswith('.zip') or url.endswith('.xls') or url.endswith('.jpg'))):
if not ( url.startswith('http://') or url.startswith('https://') ):
url= URL + url
cleanedUrl = url.lower().replace("http://",'').replace("https://",'').replace("www.",'')
if cleanedUrl.endswith("/"):
cleanedUrl = cleanedUrl[:-1]
if cleanedUrl in self.url_array:
pass
else:
self.url_array.append(url)
print(cleanedUrl)
with open(filename, 'a+') as f:
f.write(cleanedUrl+'\n')
#The spider doesn't follow redirects with status 301 and 302. If you want it to follow redirects, delete the meta object
yield Request(url, callback=self.parse, headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0'}, meta={'dont_redirect': True,"handle_httpstatus_list": [301, 302]})
На тот случай, если другой новичок Scrapy ie наткнется на это и попытается заставить этого паука работать, вот инструкции по установке :
Сохраните приведенный выше код в файл с именем hybrid_spider.py.
Установка Miniconda: https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html
Проверьте, какую версию браузера Chrome вы установили, и загрузите соответствующий chromedriver.exe из https://chromedriver.chromium.org/downloads. Затем обновите путь к chromedriver в сценарии hybrid_spider.py. (В идеале поместите его в папку с пауком)
Откройте 'Anaconda Prompt (Miniconda3), и там
- создайте новое окружение:
conda create --name crawler-test
- активируйте среда:
conda activate crawler-test
- установить Scrapy:
conda install -c conda-forge scrapy
- установить Selenium:
conda install -c conda-forge selenium
С помощью файлового проводника перейдите в каталог crawlerTest, пауки подпапок ( у меня было C: \ Users \ username \ crawlerTest \ crawlerTest \ spiders) и поместите туда hybrid_spider.py.
Для каждого веб-сайта, который вы хотите сканировать, измените информацию для входа непосредственно в сценарии hybrid_spider.py.
Чтобы начать очистку URL-адресов, в Anaconda Prompt:
- активируйте среду:
conda activate crawler-test
- перейдите в каталог crawlerTest (мой был в C: \ Users \ username \ crawlerTest)
- start spider:
python -m scrapy crawl hybrid_spider
... создаст файл urls.txt в каталоге crawlerTest. (Перезаписывает файл при каждом сканировании)