Python:python3
以下是本人在爬虫项目中遇到并积累的问题与知识点:
一、获取国内髙匿代理IP网站的免费IP代理,并验证哪些IP为可用代理,最后将可用代理输出。
首先需要爬取到代理IP的协议、ip地址、端口,本人采用了两种形式的获取:一个是常见的bs4库的BeautifulSoup与requests库,另一个是模拟浏览器selenium库。
1、PhantomJS
这里如果用selenium库需要安装PhantomJS,当然还有其他的浏览器。如下图,其中android与blackberry是移动端的浏览器,先不管。移动端的浏览器虽然支持JavaScript,但与PC段浏览器是两回事。剩下的chrome、Edge、Firefox、IE、Opera、Phantomjs和Safari比较常用。
PhantomJS是一个机遇WebKit的服务器端JavaScript API。它全面支持Web而不需浏览器支持,其快速、原生支持各种Web标准:DOM处理、CSS选择器、JSON、Canvas和SVG。PhantomJS可以用于页面自动化、网络监测、网页截屏及无界面测试等。
无界面意味着开销小、速度快。有人测试过,使用selenium调用以上的浏览器,速度最快的为PhantomJS、Chrome和IE(remote调用HtmlUnit最快,但对JavaScript不太友好)。唯一缺点就是没有GUI(界面)。
说明:
2018年3月PhantomJS的作者ariya在PhantomJS的GitHub页面说道可能会停止更新维护。在未来的通知之前,PhantomJS 2.1.1将会是已知最后的稳定版本。暂停开发的话,可以用别的工具。
例如本地调试基于Selenium+PhantomJS的动态爬虫程序顺利结束后,着手部署到服务器上,京东云安装环境,最后跑的时候报了这么个错误:
UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead
新版本的Selenium不再支持PhantomJS了,请使用Chrome或Firefox的无头版本来替代。
2、Firefox
CSDN上的孔天逸从Mozilla上提供了Selenium+Headless Firefox在Python上实现的方法:
from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as expected
from selenium.webdriver.support.wait import WebDriverWait
if __name__ == "__main__":
options = Options()
options.add_argument('-headless') # 无头参数
driver = Firefox(executable_path='geckodriver', firefox_options=options) # 配了环境变量第一个参数就可以省了,不然传绝对路径
wait = WebDriverWait(driver, timeout=10)
driver.get('http://www.google.com')
wait.until(expected.visibility_of_element_located((By.NAME, 'q'))).send_keys('headless firefox' + Keys.ENTER)
wait.until(expected.visibility_of_element_located((By.CSS_SELECTOR, '#ires a'))).click()
print(driver.page_source)
driver.quit()
作者也说了,本地要有Firefox;本地要有geckodriver,最好再配置一下环境变量;别每下载一个网页实例化一个webdriver(Firefox or Chrome)然后就close()掉,实例化webdriver的时间也是时间~推荐将下载器做成单例类或将webdirver做类变量。
3、Chrome
下载网址:https://sites.google.com/a/chromium.org/chromedriver/downloads
将解压后的chromedriver.exe放到chrome浏览器或python的安装目录下。
对于Chrome,博客园上的zhuxiaoxi提供了解决方案(需要安装chromedriver):
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("https://cnblogs.com/")
二、验证代理IP用常规requests.get(url,proxies={'https':proxy})。
requests命令会先判断proxies参数里面传入的key(http/https),看它与目标url协议是否一致,比如如果url是http,proxies里面也是传入的http,或者同是https,那么此时requests就会认为代理有效,就会通过代理来访问这个url。如果url是http,但是key是https,或者url是https,但是key是http,那么requests就会认为两者不匹配,就会直接去访问目标地址而不走代理。
一个特殊情况就是,如果url是http的,proxies的key也是http的,但是key的value我传入https代理,此时由于requests发现协议也是一致的,所以也会通过代理来请求,此时由于公司的https代理也能处理这个http请求,所以代理成功。
三、Python3中urllib就是urllib,urllib2是urllib.request。
import urllib.request # urllib2是urllib.request
if __name__ == "__main__":
#访问网址
url = 'http://www.shixi.com/search/?page=1'
#这是代理IP
ip = ip_list[1]
#设置代理ip访问方式,http和https
proxy = {'https':ip}
#创建ProxyHandler
proxy_support = urllib.request.ProxyHandler(proxy)
#创建Opener
opener = urllib.request.build_opener(proxy_support)
#添加User Angent
opener.addheaders = [('User-Agent','Mozilla/5.0')]
#安装OPener
urllib.request.install_opener(opener)
#使用自己安装好的Opener
response = urllib.request.urlopen(url)
#读取相应信息并解码
html = response.read().decode("gbk")
#打印信息
print(html)
px = urllib.request.ProxyHandler({'https':ip})
# 用build_opener()来构建一个opener对象
opener = urllib.request.build_opener(px)
headers = {
"User-Agent": "Mozilla/5.0"}
res = urllib.request.Request(url, headers=headers)
response = opener.open(res, timeout=3)
print(response)
re = response.read().decode('gbk')
print(re)
四、python动态爬取(翻页网址不变问题)
目前遇见的有两种情况:
1.拉勾网:https://www.lagou.com/gongsi/3-0-0
查看网页的变换特点,具体可以参考:https://blog.csdn.net/c350577169/article/details/80410133
2.腾讯视频vip片库:https://film.qq.com/film_all_list/allfilm.html?type=tv
这个在From Data中没有明显的特点,但是可以采用模拟浏览器点击的方式。
def next_page(url,page_number):
try:
# 等待确认按钮加载完成
browser.get(url)
confirm_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#filmPager > a.page_next.js_pager_arrow_next')))
# 确认点击翻页
confirm_btn.click()
# 确认已翻到下一页
wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#filmPager > a.page_num.current.js_page_index'),str(page_number)))
except TimeoutException:
# 若发生异常,重新调用自己
next_page(page_number)
五、使用模拟浏览器时报错
1.当使用Chrome浏览器时,需要界面滚动到显示确认按钮的地方,如果不在当前视图范围内的元素的操作,否则会报错。
当使用Firefox webdriver来测试某个页面的时候,如果选取了某个页面元素来对其进行操作,但是这个元素不在当前浏览器显示的视图范围内,Firefox webdriver的做法是自动的将视图调整到该元素显示的区域,然后对这个元素进行操作。也就是说driver自己完成了页面的scroll down or up的操作。
但是在Chrome webdriver中,如果待操作元素不在视图显示范围内,则会抛出Element is not clickable at point异常。或是如果设置了WebDriverWait并且它正常工作的话会抛出Timeout异常。因此,在使用Chrome wbedriver的时候,需要滚动页面才能显示在视图中的元素,利用代码使页面滚动至元素显示的范围,然后再对该元素进行操作。使页面滚动的方法是:
driver.execute_script("window.scrollBy(0,200)","") #向下滚动200px
driver.execute_script("window.scrollBy(0,document.body.scrollHeight)","") #向下滚动到页面底部
2.Chrome 的驱动不匹配,则也会报错,需要下载最新的放到原有目录下。
这个问题在上面也提到过,只需要检查电脑的谷歌版本是什么,然后再去Google官网下载对应版本即可。
在谷歌浏览器的右上角的设置中的帮助查看关于“Google Chrome”,这里的是71。
在该网址:https://sites.google.com/a/chromium.org/chromedriver/downloads中选择合适的版本,这里可以选择目前最新的版本ChromeDriver2.45。
打开可以看到不同的插件,选择合适的插件下载。
将解压后的chromedriver.exe放到chrome浏览器或python的安装目录下。
项目进行中,持续更新······
文章未经博主同意,禁止转载!