本篇使用 selenium技术 爬取快代理上的代理IP,并判断其是否可用。
#爬取代理IP
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.common import desired_capabilities
import time
from random import randint
from bs4 import BeautifulSoup
import pymysql
'''
PhantomJS常用配置
'''
#增加头信息
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
'Accept-Charset': 'utf-8',
"User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64;rv:47.0) Gecko/20100101 Firefox/47.0",
"Host": "www.kuaidaili.com",
"Connection": "keep-alive"
}
#DesiredCapabilities 手动设置爬取时你所期望的功能配置
for key in headers:
webdriver.DesiredCapabilities.PHANTOMJS['phantomjs.page.customHeaders.{}'.format(key)] = headers[key]
proxy=Proxy(
{
'proxyType':ProxyType.MANUAL, #manual 手工的,手动的
'httpProxy':'181.16.136.6:38319'
}
)
desired_capabilities = desired_capabilities.DesiredCapabilities.PHANTOMJS.copy()
#把代理ip加入到技能中
proxy.add_to_capabilities(desired_capabilities)
#禁止加载图片,我们只需要爬取数据,并不需要加载图片,这样可以加快爬取速度
desired_capabilities["phantomjs.page.settings.loadImages"]=False
#启动磁盘缓存
desired_capabilities["phantomjs.page.settings.disk-cache"]=True
#将配置好的PhantomJS期望的功能加入到PhantomJS驱动中
browser = webdriver.PhantomJS( desired_capabilities=desired_capabilities )
#用来存放爬取的数据
class Item(object):
ip=None
port=None
ptype=None
class spyderKuaidaili(object):
def __init__(self,url):
#连接数据库
self.db = pymysql.connect(host='localhost', port=3306,
user='root', passwd='a', db='python', charset='utf8')
self.cursor=self.db.cursor()
self.url=url
self.items=[]
try:
browser.get(url)
for i in range(10): #循环十次,爬取十页
time.sleep( randint(2,5) ) #爬取太勤快会被封ip的
result=browser.page_source #得到网页源码
list1=self.parseHtml(result) #去解析该网页,得到需要的数据
self.items.append(list1) #得到的数据添加到列表里去
#这一页代理获取完成,开始selenium自动点击下一页,首先需得到下一页的标签
aTags=browser.find_elements_by_xpath("//div[@id='listnav']/ul/li/a")
for aElement in aTags:
#如果元素是 invisable 的,则用text取不到,只能用innerHTML取
#print( aElement.get_attribute('innerHTML') )
if aElement.get_attribute('innerHTML')==str(i+2):
#满足条件,则是需要点击的那一页
print('点击了第:',str(i+2),'页')
aElement.click() #aElement本身是个a标签,点击则执行href跳转到相应页面
browser.switch_to.window(browser.window_handles[0])
break
except Exception as e:
print('a==========%s' % e )
print("爬取完毕...")
self.cursor.close()
self.db.close()
browser.close()
browser.quit()
print("已关闭浏览器...")
def parseHtml(self,content):
items=[]
soup=BeautifulSoup(content,'lxml')
divTag=soup.find('div',attrs={'id':'list'})
tags=divTag.table.tbody.find_all('tr')
for tag in tags:
item=Item()
item.ip=tag.find('td',attrs={'data-title':'IP'}).get_text().strip()
item.port=tag.find('td',attrs={'data-title':'PORT'}).get_text().strip()
item.ptype=tag.find('td',attrs={'data-title':'类型'}).get_text().strip()
items.append(item) #将得到的item对象存入列表
print( item.ip,' ',item.port,' ',item.ptype )
#将一页的数据一起存入数据库
self.insert(items)
return items
def insert(self,items): #[Item,Item...Item]
print("开始插入数据库")
sql='insert into kuaidaili(kip,kport,kptype) values(%s,%s,%s)'
params=[]
for item in items:
params.append( ( item.ip,item.port,item.ptype ) )
try:
#进行批量插入
self.cursor.executemany(sql,params)
self.db.commit()
except Exception as e:
print("插入数据库异常")
self.db.rollback()
if __name__=='__main__':
url='https://www.kuaidaili.com/free/inha/'
spyderKuaidaili(url)
下面是输出的首尾截图:
好了,我们已经爬取到了十页的代理IP了。但是,这些免费的IP并不是所有的都是能使用的,所以,我们需要再将这些代理IP进行判断,把有用的选出来。
import requests
import pymysql
#将上面存入数据库的代理IP拿出来做判断
def getIpFromMysql():
db=pymysql.connect(host='localhost',port=3306,
user='root',passwd='a',db='python',charset='utf8')
cursor=db.cursor()
sql='select * from kuaidaili'
try:
cursor.execute(sql)
results=cursor.fetchall()
allIp=[]
for row in results:
lst=[]
kip=row[1]
kport=row[2]
kptype=row[3]
ip=[kip,kport,kptype]
allIp.append(ip)
checkIp( allIp ) #将所有ip拿去检测
except:
print('查询报错')
class checkIp(object):
def __init__(self,allIp):
self.allIp=allIp
self.check()
def check(self):
for ip in self.allIp:
kip=ip[0]
kport=ip[1]
kptype=ip[2].lower()
url=kptype+"://"+kip+":"+kport
print(url)
try:
#使用代理ip去访问百度,如果ip不能用,则会报错
requests.get( 'http://www.baidu.com', proxies={ kptype:url } )
except:
print('=============================failure')
else:
print('=============================success')
if __name__=='__main__':
getIpFromMysql()
得到的结果部分截图如下:
感谢您的阅读!