反爬虫:python多进程获取代理加入队列并用代理爬虫

写在前面

我们都知道,免费代理网站的代理质量都不高,主要体现在,比如代理A前一秒可用,后一秒可能就用不了了。所以如果你爬取的代理池,和用这些代理访问目标网站之间的时间过长,这些代理很可能就用不了。所以我就想了一个办法,能不能用多进程一边获取代理,一边用这些代理爬虫,提高代理的利用率。

主要用到的库和知识点

  1. requests库
  2. fake_useragent库,伪造浏览器访问代理网站,因为怕被代理网站封了我的IP
  3. telnetlib库,测试一个代理是否可用
  4. multiprocessing库的Process,多进程实现一边爬取代理,一边用代理爬虫
  5. multiprocessing库的Queue,实现进程间信息的交互

代码

具体思路可以见注释

# encoding=utf-8
import requests
from fake_useragent import UserAgent
from lxml import etree
import telnetlib
import time
from multiprocessing import Queue, Process
'''
get_proxy方法的作用
1.‘循环’从泥马代理官网的代理中进行第一次筛选,筛选出可用的代理
2.将第一次筛选的代理放入‘队列q_0’
3.当‘队列q_1’不为空时,结束循环

get_page方法的作用
1.从‘队列q_0’里获取代理
2.用步骤1的代理访问目标页面,进行二次筛选,访问不了目标页面的话,该代理就被筛掉
3.若访问成功,则‘加入0’到‘队列q_1’,结束循环,返回页面源代码;若访问不成功,则返回到步骤1

'''
#
# 2.
def get_proxy(q_0, q_1):
    n = 0
    while q_1.empty():  # 如果队列q_1为空,说明get_page方法并没有成功访问到目标页面,循环继续
        n += 1
        print('第{0}次爬取'.format(n))
        ua = UserAgent()
        useragent = ua.random  # 伪造随机浏览器
        headers = {'User-Agent': useragent}
        url = 'http://www.nimadaili.com/'
        res = requests.get(url, headers)
        if res.status_code == 200:
            pageContent = res.text
            html = etree.HTML(pageContent)
            proxy = html.xpath('//*[@id="overflow"]/table/tbody/tr/td[1]/node()')
            proxy = proxy[:30]
        else:
            proxy = []
            print('代理网页访问失败!')
        for pr in proxy[:-1]:
            ip, port = str(pr).split(':')
            try:
                telnetlib.Telnet(ip, port, timeout=2)  # 测试代理是否可用
                print(str(pr), 'OK!')
                q_0.put(str(pr))  # 队列q_0里放入第一次筛选后,可用的代理
            except Exception as e:
                print(str(pr), 'ERROR!')
        print('WAIT...')
        time.sleep(6)

def get_page(q_0, q_1, url):
    while True:
        pro = str(q_0.get())  # 获取队列q_0里,可用的代理
        print('Get %s from queue.' % pro)
        proxies = {
            'http': 'http://' + pro,
            'https': 'https://' + pro,
        }
        try:
            response = requests.get(url, proxies=proxies)  # 用代理访问目标页面
            break
        except Exception as e:
            continue
    response.encoding = 'utf-8'
    pageContent = response.text
    print('pageContent:', pageContent)
    q_1.put(0)
    return pageContent

if __name__=='__main__':
    q_0 = Queue()
    q_1 = Queue()
    url = 'https://www.baidu.com'
    pw = Process(target=get_proxy, args=(q_0, q_1))
    pr = Process(target=get_page, args=(q_0, q_1, url))
    pw.start()
    pr.start()
    pw.join()
    pr.join()

写在后面

如果大家有问题,可以一起讨论哈!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值