美文网首页
使用python抓取免费代理地址

使用python抓取免费代理地址

作者: 单身狗的清香 | 来源:发表于2017-04-30 18:25 被阅读1350次

玩过python爬虫的小伙伴们都知道,网站的反爬虫策略之一就是IP黑名单,也就是不能用同一个ip地址连续多次爬取一个网站的数据,爬得多了,网站的反爬虫策略就会把这个ip地址加入到黑名单中,那么除非你更换ip,否则就再也获取不到数据了,也有可能陷入爬虫陷阱或被其他反爬虫策略制裁:),所以我们需要不断的更换自己的ip地址来伪装自己,所以我们得准备一大堆代理ip。

随便google了一下免费代理,出现的第一个就是这个:免费代理

我们就使用强大的python三方库开搞吧,主要用到的有bs4,requests和
sqlite3

其中bs4和requests都是最常见的爬虫标配库,sqlite3是一个很好用的python官方库。

1.先获取目标网站的html数据

import requests # 导入
    header = {  # 添加header可以将程序伪装成浏览器
    "Host": "www.kuaidaili.com",
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, sdch',
    'Accept-Language': 'zh-CN,zh;q=0.8',
}
TARGET_URL = ("http://www.kuaidaili.com/free/inha/1)  # 目标地址
html = requests.get(url=TARGET_URL, headers=header, timeout=30).content  # 获取html文本
print(html)

在chrome中打开目标地址,按F12,检查网页代码,可以看到我们想要的数据都在table标签的一个个tr标签中

源数据格式

那么我们拿到html文本之后,只要对其进行解析和过滤,就可以拿到我们想要的数据了。

2.解析html

这里用到了强大的bs4库中的BeautifulSoup类,当然正则表达式掌握的非常熟练的同学可以直接使用正则去匹配,那样的话,效率会更高。
对BeautifulSoup不熟悉的同学,可以查看官方文档

from bs4 import BeautifulSoup# 导入三方库
soup = BeautifulSoup(html, 'lxml')  # 创建一个BeautifulSoup,使用更强的lxml解析器,
                                    # 需要提前安装
list_tr = soup.find('div', id='list').find_all('tr')  # 提取id为list的div标签中的所有tr标签
for i in range(len(list_tr)):  # 遍历tr标签的列表
    if i == 0: continue  # 因为从上图中我们可以看到第一个tr标签里面的内容是表头,
                        # 不是我们需要的数据,所以我们跳过第一个tr标签,从第二个tr标签开始遍历
    tr = list_tr[i]
    list_td = tr.find_all('td')# 获取每个tr标签中的所有td标签,分析html可知td标签从上到下
                                # 依次是ip,端口,匿名度等信息...

    ip = list_td[0].get_text()
    port = list_td[1].get_text()
    anonymous = list_td[2].get_text()
    types = list_td[3].get_text()
    location = list_td[4].get_text()
    speed = list_td[5].get_text()
    verify_time = list_td[6].get_text()
    # 创建代理对象,把每个代理信息都保存到对象中,这一步也可以跳过
    daili = Daili(ip, port, anonymous, types, location, speed, verify_time)

3.保存数据

拿到了大量的数据之后,肯定是得保存起来,供日后使用,这里用sqlite数据库进行保存,它与mysql相比是一个更简单和轻量级的数据库,完全可以满足目前的需求。

import sqlite3
if not os.path.exists('ip.db'):# 检查数据库文件是否存在
    self.create_table()  # 创建数据库
conn = sqlite3.connect('ip.db')# 建立连接
cursor = conn.cursor()# 创建操作游标

sql = "INSERT INTO ip(ip,port,anonymous,types,location,speed,verify_time) VALUES (" + str(
    '\'' + daili.ip + '\',\'' + daili.port + '\',\'' + daili.anonymous + '\',\'' + daili.types + '\',\'' + daili.location + '\',\'' + daili.speed + '\',\'' + daili.verify_time) + '\')'

cursor.execute(sql)# 执行sqlite语句
conn.commit()# 最后不要忘了提交操作
conn.close()

4.最后对代码进行简单的封装

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by master on 2017/4/7
import os
import requests
from bs4 import BeautifulSoup
import sqlite3

from Kuaidaili.FreeDaili import Daili


class KuaiDaili(object):
    def get_html(self, page):
        header = {  # 添加header可以将程序伪装成浏览器
            "Host": "www.kuaidaili.com",
            'Connection': 'keep-alive',
            'Cache-Control': 'max-age=0',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Accept-Encoding': 'gzip, deflate, sdch',
            'Accept-Language': 'zh-CN,zh;q=0.8',
        }
        TARGET_URL = ("http://www.kuaidaili.com/free/inha/%s" % page)  # 目标地址
        html = requests.get(url=TARGET_URL, headers=header, timeout=30).content  # 获取html文本
        return html.decode("utf-8")

    def create_table(self):
        conn = sqlite3.connect('ip.db')
        cursor = conn.cursor()
        cursor.execute(
            '''CREATE TABLE ip (id INTEGER PRIMARY KEY ,
                ip VARCHAR(20) ,
                port BOOLEAN ,
                anonymous VARCHAR(20) ,
                types VARCHAR(20) ,
                location VARCHAR(20) ,
                speed VARCHAR(20) ,
                verify_time VARCHAR(20))
            ''')
        conn.commit()

    def insert_ip(self, daili):
        if not os.path.exists('ip.db'):
            self.create_table()  # 创建数据库
        conn = sqlite3.connect('ip.db')
        cursor = conn.cursor()
        sql = "INSERT INTO ip(ip,port,anonymous,types,location,speed,verify_time) VALUES (" + str(
            '\'' + daili.ip + '\',\'' + daili.port + '\',\'' + daili.anonymous + '\',\'' + daili.types + '\',\'' + daili.location + '\',\'' + daili.speed + '\',\'' + daili.verify_time) + '\')'

        daili.__str__()
        cursor.execute(sql)
        conn.commit()

    def ip_list(self, html):
        soup = BeautifulSoup(html, 'lxml')  # 创建一个BeautifulSoup,使用更强的lxml解析器,
                                            # 需要提前安装
        list_tr = soup.find('div', id='list').find_all('tr')  # 提取id为list的div标签中的所有tr标签
        for i in range(len(list_tr)):  # 遍历tr标签的列表
            if i == 0: continue  # 因为从上图中我们可以看到第一个tr标签里面的内容是表头,
                                # 不是我们需要的数据,所以我们跳过第一个tr标签,从第二个tr标签开始遍历
            tr = list_tr[i]
            list_td = tr.find_all('td')# 获取每个tr标签中的所有td标签,分析html可知td标签从上到下
                                        # 依次是ip,端口,匿名度等信息...

            ip = list_td[0].get_text()
            port = list_td[1].get_text()
            anonymous = list_td[2].get_text()
            types = list_td[3].get_text()
            location = list_td[4].get_text()
            speed = list_td[5].get_text()
            verify_time = list_td[6].get_text()
            # 创建代理对象,把每个代理信息都保存到对象中,这一步也可以跳过
            daili = Daili(ip, port, anonymous, types, location, speed, verify_time)


            self.insert_ip(daili)# 插入数据

    def batch_insert(self, page=10):# 批量插入
        for i in range(1, page):
            resp = self.get_html(i)
            self.ip_list(resp)

    def query(self):# 查询数据
        conn = sqlite3.connect('ip.db')
        cursor = conn.cursor()
        # sql = 'select ip,port from ip where location like "中国 江苏省 镇江市%";'
        # sql = 'select * from ip where port="80";'
        sql = 'select * from ip;'
        rows = cursor.execute(sql)

        for row in rows:
            print(str(row[0]) + ":" + str(row[1]))
        print('rows length:%s', len(rows))
        conn.commit()
        conn.close()


if __name__ == '__main__':
    daili = KuaiDaili()
    daili.batch_insert()# 在这里可以传入你想爬取多少页数据,默认的话是10页

最后是抓取的成果:

成果

总结

整个程序非常的简单,得益于python强大的三方库支持,我们可以仅仅使用几行代码就能实现想要的功能,但是建议克制使用爬虫,以免给目标网站造成巨大的服务器压力,从而影响正常的用户访问。
源码

相关文章

网友评论

      本文标题:使用python抓取免费代理地址

      本文链接:https://www.haomeiwen.com/subject/lgrxtxtx.html