先谈谈用 Scrapy 框架爬取数据搭配使用 Selenium 的原因:
一般情况下我们使用 Scrapy 就可以完成所有爬取操作,但是爬取过程会遇到某些操作用代码实现非常复杂,比如我写过的这篇博客 Scrapy 模拟登录新版知乎 其中的 signature 参数的值,是在某个 js 中通过算法加密生成的,很麻烦;但是我们不登录的话爬取的数据可能会不全面,,有没有一种更好的办法?答案是肯定的!那就是 Selenium,完全模拟人去操作浏览器;下面我通过在某商标网站模拟登录后爬取详情数据为例告诉大家怎么搭配使用 Selenium + Scrapy,本篇只介绍用法,默认已安装了 Selenium 和 Scrapy
1、Selenium 模拟登录
def start_requests(self):
url = "https://account.quandashi.com/passport/login?callback=https%3A%2F%2Fwww.quandashi.com%2F"
driver = webdriver.Chrome(executable_path='E:\Develop\chromedriver_win32\chromedriver.exe') # 指定你安装的 chromedriver 目录,这儿使用的是Chrome, 当然你也可以换成 Firefox
driver.get(url)
time.sleep(5) # 延时的原因是等网页加载完毕再去获取字段
driver.find_element_by_xpath('//*[@id="username"]').send_keys("用户名") # 用户名输入框
driver.find_element_by_xpath('//input[@type="password"]').send_keys("密码") # 密码输入框
driver.find_element_by_xpath('//*[@id="btn-login"]').click() # 登录按钮
time.sleep(15)
cookie = driver.get_cookies() # 获取登录后的 cookies
yield scrapy.Request(url="https://so.quandashi.com/index/search?key=查询关键字",
headers=self.headers, dont_filter=True, cookies=cookie, meta={"cookie": cookie})
以上操作是通过 Selenium 模拟登录后获取到对应的 coookie,后面的每次请求都带上该 cookie
2、Scrapy 请求数据
def parse(self, response):
dl_nodes = response.xpath('//div[@class="searchLis-result"]/dl')
cookie = response.meta.get("cookie", ""),获取传过来的 cookie 值
for node in dl_nodes:
detail_url = node.xpath('dt/span/a/@href').extract_first() # xpath匹配规则,获取详情页的 url
yield scrapy.Request(url=urlparse.urljoin(response.url, detail_url), headers=self.headers, dont_filter=True,
cookies=cookie, meta={"cookie": cookie, "present_status": present_status},
callback=self.parse_detail) # 每次请求都需要携带 cookie 值
def parse_detail(self, response):
print(response.text)
添加 parse_detail 函数处理传过来的详情页数据,打印会发现里面就是详情 url 所对应的详情数据 完整的源码
总结
我们可以使用 Selenium 来代码一些代码实现起来很复杂的操作,当然上面的例子没有进行适合的封装,仅仅是介绍了 Selenium + Scrapy 的用法,比如 Scrapy 所有的 url 下载操作都会经过中间件 DownloaderMiddleware,因此我们可以将 cookie 下载到本地,然后在中间件给 request 的每个 url 加上 cookie,这样代码可读性更好,而且代码更严谨
网友评论