身份验证后每 link 抓取一次 Scrapy
Scrapy crawl every link after authentication
简介
由于我的爬虫或多或少已经完成,我需要重做一个只爬取整个 domain links 的爬虫,我的工作需要这个。
每 link 爬行的蜘蛛应该每月 运行 一次。
我是 运行ning scrapy 2.4.0,我的 os 是 Linux Ubuntu server 18.04 lts
问题
我要爬取的网站改变了他们的“隐私”,所以你必须先登录才能看到产品,这就是为什么我的“link爬虫”不再工作的原因。
我已经设法登录并抓取了我所有的东西,但是 start_urls 在 csv 文件中给出。
代码
import scrapy
from ..items import DuifItem
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.http import FormRequest, Request
from scrapy_splash import SplashRequest
class DuifLinkSpider(CrawlSpider):
name = 'duiflink'
allowed_domains = ['duif.nl']
login_page = 'https://www.duif.nl/login'
start_urls = ['https://www.duif.nl']
custom_settings = {'FEED_EXPORT_FIELDS' : ['Link']}
def start_requests(self):
yield SplashRequest(
url=self.login_page,
callback=self.parse_login,
args={'wait': 3},
dont_filter=True
)
rules = (
Rule(LinkExtractor(deny='https://www.duif.nl/nl/'), callback='parse_login', follow=True),
)
def parse_login(self, response):
return FormRequest.from_response(
response,
formid='login-form',
formdata={
'username' : 'not real',
'password' : 'login data'},
clickdata={'type' : 'submit'},
callback=self.after_login)
def after_login(self, response):
accview = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]//a/@href')[13]
if accview:
print('success')
else:
print(':(')
for url in self.start_urls:
yield response.follow(url=url, callback=self.search_links)
def search_links(self, response):
link = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]/li/a/@href').get()
for a in link:
link = response.url
yield response.follow(url=link, callback=self.parse_page)
def parse_page(self, response):
productpage = response.xpath('//div[@class="product-details col-md-12"]')
if not productpage:
print('No productlink', response.url)
for a in productpage:
items = DuifItem()
items['Link'] = response.url
yield items
很遗憾,我无法提供一个虚拟帐户,您可以在其中尝试自己登录,因为它是一个 b2b 服务网站。
我可以想象我的“def search_links”是错误的。
我计划的结构是:
- 访问login_page,传递我的登录凭据
- 检查是否通过 xpath 登录,检查是否提供注销按钮。
- 如果登录,它会打印 'success'
- 由 xpath 表达式给出,它应该从 links 开始:
- 通过访问每个 link,它应该通过 xpath xpression 检查是否给出了特定的容器,所以它知道它是否是产品页面。
- 如果是产品页面,保存访问过的link,如果不是产品页面,则进入下一个link
控制台输出
如您所见,身份验证有效,但之后不会执行任何操作。
更新
我稍微修改了我的代码:
import scrapy
from ..items import DuifItem
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.http import FormRequest, Request
from scrapy_splash import SplashRequest
class DuifLinkSpider(CrawlSpider):
name = 'duiflink'
allowed_domains = ['duif.nl']
login_page = 'https://www.duif.nl/login'
start_urls = ['https://www.duif.nl/']
custom_settings = {'FEED_EXPORT_FIELDS' : ['Link']}
def start_requests(self):
yield SplashRequest(
url=self.login_page,
callback=self.parse_login,
args={'wait': 3},
dont_filter=True
)
rules = (
Rule(LinkExtractor(), callback='parse_login', follow=True),
)
def parse_login(self, response):
return FormRequest.from_response(
response,
formid='login-form',
formdata={
'username' : 'not real',
'password' : 'login data'},
clickdata={'type' : 'submit'},
callback=self.after_login)
def after_login(self, response):
accview = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]//a/@href')[13]
if accview:
print('success')
else:
print(':(')
for url in self.start_urls:
yield response.follow(url=url, callback=self.search_links, dont_filter=True)
def search_links(self, response):
# link = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]/li/a/@href')
link = response.xpath('//a/@href')
for a in link:
link = a.get()
link = 'https://www.duif.nl' + link if link else link
yield response.follow(url=link, callback=self.parse_page, dont_filter=True)
def parse_page(self, response):
productpage = response.xpath('//div[@class="product-details col-md-12"]')
if not productpage:
print('No productlink', response.url)
for a in productpage:
items = DuifItem()
items['Link'] = response.url
yield items
现在我知道,我确实登录了,但它不遵循“sub”-links,但我想如果我使用 response.xpath('//a/@href')
,它会自动搜索整个dom 每 link.
低于我的新控制台输出
登录后,您将返回解析开始 url。默认情况下,Scrapy 会过滤掉重复的请求,因此在您的情况下它会在此处停止。您可以通过在请求中使用 'dont_filter=True' 来避免这种情况,如下所示:
yield response.follow(url=url, callback=self.search_links, dont_filter=True)
简介
由于我的爬虫或多或少已经完成,我需要重做一个只爬取整个 domain links 的爬虫,我的工作需要这个。 每 link 爬行的蜘蛛应该每月 运行 一次。
我是 运行ning scrapy 2.4.0,我的 os 是 Linux Ubuntu server 18.04 lts
问题
我要爬取的网站改变了他们的“隐私”,所以你必须先登录才能看到产品,这就是为什么我的“link爬虫”不再工作的原因。 我已经设法登录并抓取了我所有的东西,但是 start_urls 在 csv 文件中给出。
代码
import scrapy
from ..items import DuifItem
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.http import FormRequest, Request
from scrapy_splash import SplashRequest
class DuifLinkSpider(CrawlSpider):
name = 'duiflink'
allowed_domains = ['duif.nl']
login_page = 'https://www.duif.nl/login'
start_urls = ['https://www.duif.nl']
custom_settings = {'FEED_EXPORT_FIELDS' : ['Link']}
def start_requests(self):
yield SplashRequest(
url=self.login_page,
callback=self.parse_login,
args={'wait': 3},
dont_filter=True
)
rules = (
Rule(LinkExtractor(deny='https://www.duif.nl/nl/'), callback='parse_login', follow=True),
)
def parse_login(self, response):
return FormRequest.from_response(
response,
formid='login-form',
formdata={
'username' : 'not real',
'password' : 'login data'},
clickdata={'type' : 'submit'},
callback=self.after_login)
def after_login(self, response):
accview = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]//a/@href')[13]
if accview:
print('success')
else:
print(':(')
for url in self.start_urls:
yield response.follow(url=url, callback=self.search_links)
def search_links(self, response):
link = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]/li/a/@href').get()
for a in link:
link = response.url
yield response.follow(url=link, callback=self.parse_page)
def parse_page(self, response):
productpage = response.xpath('//div[@class="product-details col-md-12"]')
if not productpage:
print('No productlink', response.url)
for a in productpage:
items = DuifItem()
items['Link'] = response.url
yield items
很遗憾,我无法提供一个虚拟帐户,您可以在其中尝试自己登录,因为它是一个 b2b 服务网站。
我可以想象我的“def search_links”是错误的。
我计划的结构是:
- 访问login_page,传递我的登录凭据
- 检查是否通过 xpath 登录,检查是否提供注销按钮。
- 如果登录,它会打印 'success'
- 由 xpath 表达式给出,它应该从 links 开始:
- 通过访问每个 link,它应该通过 xpath xpression 检查是否给出了特定的容器,所以它知道它是否是产品页面。
- 如果是产品页面,保存访问过的link,如果不是产品页面,则进入下一个link
控制台输出
如您所见,身份验证有效,但之后不会执行任何操作。
更新
我稍微修改了我的代码:
import scrapy
from ..items import DuifItem
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.http import FormRequest, Request
from scrapy_splash import SplashRequest
class DuifLinkSpider(CrawlSpider):
name = 'duiflink'
allowed_domains = ['duif.nl']
login_page = 'https://www.duif.nl/login'
start_urls = ['https://www.duif.nl/']
custom_settings = {'FEED_EXPORT_FIELDS' : ['Link']}
def start_requests(self):
yield SplashRequest(
url=self.login_page,
callback=self.parse_login,
args={'wait': 3},
dont_filter=True
)
rules = (
Rule(LinkExtractor(), callback='parse_login', follow=True),
)
def parse_login(self, response):
return FormRequest.from_response(
response,
formid='login-form',
formdata={
'username' : 'not real',
'password' : 'login data'},
clickdata={'type' : 'submit'},
callback=self.after_login)
def after_login(self, response):
accview = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]//a/@href')[13]
if accview:
print('success')
else:
print(':(')
for url in self.start_urls:
yield response.follow(url=url, callback=self.search_links, dont_filter=True)
def search_links(self, response):
# link = response.xpath('//ul[@class="nav navbar-nav navbar-secondary navbar-right"]/li/a/@href')
link = response.xpath('//a/@href')
for a in link:
link = a.get()
link = 'https://www.duif.nl' + link if link else link
yield response.follow(url=link, callback=self.parse_page, dont_filter=True)
def parse_page(self, response):
productpage = response.xpath('//div[@class="product-details col-md-12"]')
if not productpage:
print('No productlink', response.url)
for a in productpage:
items = DuifItem()
items['Link'] = response.url
yield items
现在我知道,我确实登录了,但它不遵循“sub”-links,但我想如果我使用 response.xpath('//a/@href')
,它会自动搜索整个dom 每 link.
低于我的新控制台输出
登录后,您将返回解析开始 url。默认情况下,Scrapy 会过滤掉重复的请求,因此在您的情况下它会在此处停止。您可以通过在请求中使用 'dont_filter=True' 来避免这种情况,如下所示:
yield response.follow(url=url, callback=self.search_links, dont_filter=True)