Beautiful Soup其实不是一个爬虫框架,它仅仅是一个模块,用于解HTML的网页内容,非常强大。而Selenium则是一个轻量级的爬虫框架,它能够选择浏览器核心,模拟浏览器登录网页,从而运行JavaScript代码,进而生成静态的HTML内容。两者可以结合使用,即先由Selenium+任意浏览器内核将动态的JavaScript网页转化为HTML内容,然后再由Beautiful Soup进行解析。需要注意以下几个问题:
Selenium的浏览器内核选择
Selenium支持许多浏览器内核,包括Chrome, IE, Edge, Firefox, Phantomjs和Safari。其中Phantomjs是无界面的基于Webkit的浏览器,所以速度最快,适合爬虫。我主要采用了下面两种浏览器内核。
(1)安装Phantomjs 从phantomjs.org网站下载Windows版的PhantomJS,解压后将phantomjs.exe放在python的安装目录python27下,因为该目录已经被加入系统路径中,所以就可以不用路径,直接调用了。
(2)安装Chrome headless Chromedriver的下载 http://chromedriver.storage.googleapis.com/index.html 2.36版本就支持Chrome65了。 看里面的readme。
请求中设置userAgent问题
请求中可以加入“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36”这种UserAgent,要在.py文件里加入下面的代码
#替换UserAgent
desired_capabilities["phantomjs.page.setting.userAgent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
#使用Chrome headless的写法
browser = webdriver.Chrome(executable_path=chrome_path, chrome_options=options,desired_capabilities=desired_capabilities)
#使用PhantomJS的写法
browser = webdriver.PhantomJS(desired_capabilities=desired_capabilities,service_args=['--ignore-ssl-errors=true'])
设置Proxy
设置Proxy非常高不稳定,由可能返回空网页,要注意处理这种异常。 返回空网页的原因,有两个:
(1)windows Defender阻止了你修改代理,需要点击一下确认,可以先启动图形界面,确认后,再恢复无图界面;
(2)代理本身的问题,多试几次就可以了。
命令行方式调用PhantomJS
下面再给出一种不使用Selenium,直接用命令行调用PhantomJS,也可以设置代理和伪装UserAgent。
#命令行方式调用PhantomJS,命令行参数中第一个参数是proxy,第二各参数是PhantomJS要解析的code.js文件,第三个参数是要访问的url地址
#该url地址会被code.js接收,具体看下面code.js的代码。
def getResponse(self,url):
self.writeJSFile()
cmd= "phantomjs --proxy=114.113.126.86:80 code.js {}".format(url)
obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
content = obj.stdout.read()
obj.stdout.close()
return content
#第二个参数code.js产生自下面的函数,其中完成了UserAgent的伪装。
def writeJSFile(self):
f = open("code.js", "w+")
#设置了UserAgent在code.js文件中
f.write("system = require('system')\n address = system.args[1];\n var page = require('webpage').create(); \nvar url = address;\npage.settings.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36';\npage.open(url, function (status) { \n if (status !== 'success'){\n console.log('Unable to post!'); \n } else { \n console.log(page.content);\n }\n phantom.exit();\n});")
f.close()
最终,上述writeJSFile函数产生并被getResponse函数调用的code.js的内容如下:
system = require('system')
address = system.args[1];
var page = require('webpage').create();
var url = address;
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36';
page.open(url, function (status) {
if (status !== 'success'){
console.log('Unable to post!');
} else {
console.log(page.content);
}
phantom.exit();
});