Python—selenium爬取快代理

本篇使用 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()
    

得到的结果部分截图如下:

在这里插入图片描述

感谢您的阅读!

猜你喜欢

转载自blog.csdn.net/qq_39022311/article/details/84191046