scrapy 集成 selenium
来源:9-4 selenium集成到scrapy中
JaydenJune
2020-11-21
你好老师:
假设当一个新闻列表页是静态页面,而新闻详情页是动态加载页面.当加载新闻列表页时不需要selenium,而加载新闻详情页时需要.我的middleware这样写对不对,你给看一下. 请看一下代码里的注释,方便你理解我的意思.
如果我的代码成立的话,是不是可以理解为,middleware拦截符合我们条件的url,browser拿着此url请求动态页面的完整数据.此url不会交给downloader.不符合我们条件的url,middleware不会拦截,仍然交给downloader来处理.
class CnblogSpider(scrapy.Spider):
name = 'cnblog'
allowed_domains = ['news.cnblogs.com']
start_urls = ['http://news.cnblogs.com/']
def __init__(self):
self.browser = webdriver.Chrome(executable_path="E:/chromedriver_win32/chromedriver.exe")
super(CnblogSpider, self).__init__()
dispatcher.connect(self.spider_closed, signals.spider_closed)
def parse(self, response, **kwargs):
# 对一条数据测试爬取
post_nodes = response.css('#news_list .news_block')[:1]
for post_node in post_nodes:
image_url = post_node.css(".entry_summary a img::attr(src)").extract_first("")
image_url = parse.urljoin("https:", image_url)
post_url = post_node.css(".news_entry a::attr(href)").extract_first("")
# 获取到新闻详情页url,发起请求.这个url请求会被middleware拦截到.使用browser来获取动态数据.
yield Request(url=parse.urljoin(response.url, post_url), meta={"news_image_head_url": image_url},
callback=self.parse_detail)
class JSPageDownloaderMiddleware:
def process_request(self, request, spider):
# 判断是哪一个爬虫
if spider.name == "cnblog":
# 假设https://news.details.com是一个详情页的url
# 判断是否是新闻详情页的url,是的话调用browser请求数据.而列表详情页的url不会被拦截,让downloader来处理.
if request.url == "https://news.details.com":
spider.browser.get(request.url)
import time
time.sleep(3)
return HtmlResponse(url=spider.browser.current_url, body=spider.browser.page_source, encoding="utf-8",
request=request)
写回答
1回答
-
bobby
2020-11-22
是的,只要你的process_request中返回了response了,那么engine不会将这个交给downloader下载,而是直接走pipeline流程了
042020-12-03
相似问题