爬虫小练(刷访问量)(python+requests(headers+proxy)+Queue+threading)

声明

本博客只限于学习和交流,作为一个爬虫小练习实现这样的一个功能。
在文末可以获取最终成型的代码,但是为了防止拿来主义代码中会故意存在漏洞。只有认真,至少是阅读了这篇博客,或者代码才可以发现这些错误。

访问机制

首先我们先打开一个页面
在这里插入图片描述
此时的访问量是45.那么接下来我们先尝试一下过一段时间再用同一个浏览器再次访问,(这里不考虑中间有人访问我的博客因为本人的博客确实没人看,否则小爷我写这篇博客干嘛)
在这里插入图片描述
这里我只是简单的刷新了几次隔一段时间就刷一次访问量就增加了4.那么基于此原理我么不妨先试试使用爬虫简单做一下访问查看访问量是否增加。

模拟访问

现在是时候请出python爬虫了。
代码如下;

import re
import requests
from requests import RequestException
import time
import random


def get_pae(url):##
    try:
        headers = {
    
    
            'Referer': 'https://blog.csdn.net',  # 伪装成从CSDN博客搜索到的文章
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'
        # 伪装成浏览器
        }
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        print('请求出错')
        return None


def parse_page(html):
    try:
        '''获取当前博客访问量'''
        read_num = int(re.compile('<span class="read-count">(.*?)</span>').search(html).group(1))
        return read_num
    except Exception:
        print('解析出错')
        return None

def view_pa_ge(url):###
    html = get_page(url)
    if html:
        read_num = parse_page(html)
        if read_num:
            print('当前阅读量:', read_num)

def main():
    try:
        while True:
            '''填入待访问的博客下面刷取四个博客访问量'''
            url = 'https://blog.csdn.net/FUTEROX/article/details/107869258'
            view_page(url)
            url = 'https://blog.csdn.net/FUTEROX/article/details/107869189'
            view_page(url)
            url = 'https://blog.csdn.net/FUTEROX/article/details/107869159'
            view_page(url)
            url = 'https://blog.csdn.net/FUTEROX/article/details/107498267'
            view_page(url)
            sleep_time = random.randint(60, 80)
            print('please wait', sleep_time, 's')
            time.sleep(sleep_time)  # 设置访问频率,过于频繁的访问会触发反爬虫
    except Exception:
        print('刷取错误')


if __name__ == '__main__':
    main()



运行结果如下;

在这里插入图片描述
看起来,我们的代码具有效果。但是等待时间过长,现在试着稍微改短一点
在这里插入图片描述
这里的访问量并没有提升,所以我们必须等待一分钟左右后访问才能有效否则作废,到时候可能还会被服务器怀疑。

问题漏洞

此外似乎还存在一个问题,访问的时间间隔要一分钟左右但是这样做似乎也太慢了。也许你会说使用多线程来解决一下问题,但是你见过一个人用同一个浏览器疯狂看几篇博客不间断的么。使用多线程的效果无非与将等待时间改短因为用来用去都是同一个IP在那里访问。如下图;
在这里插入图片描述
其中IP地址一可以看作是一个人,乍一看这种操作没问题,我看不懂多看几次。但是1W+之后在一天之间就如此操作你确定服务器是不会报错。发现你是一个爬虫后反制,所以这个方式并不适合大规模的访问。想要以此上1000+是不太可能的。

更好的”伪装“

刚刚我们使用的是本机ip和同一个浏览器通过不同时段的访问从而达到一个效果,但是主页中显示的改博客访问量不增加。这里其实想也知道说白了就是同一台电脑在不断的访问,阅读量的确算是增加了但是可能还只是同一个人。
如下图;
在这里插入图片描述
所以干脆玩高级一点的。
在这里插入图片描述
这样看上去就高级多了,看上去也更符合实际情况。而且看上去也似乎不需要再等待一分钟左右了,就好像一个人博客火了不到几秒就有一个用户去访问一样。

获取代理开始升级

来这里分享几个代理获取的好地方;
http://ip.kxdaili.com/ 开心代理
https://proxy.mimvp.com/free.php 米扑代理
http://www.xiladaili.com/ 西拉免费代理IP
http://ip.jiangxianli.com/ 免费代理IP库
http://www.superfastip.com/ 极速代理
http://ip.kxdaili.com/ 开心代理
https://proxy.mimvp.com/free.php 米扑代理
http://www.shenjidaili.com/open/ 神鸡代理IP
http://31f.cn/http-proxy/ 三一代理
http://www.feiyiproxy.com/?page_id=1457 飞蚁代理
http://ip.zdaye.com/dayProxy/2019/4/1.html 站大爷
http://www.66ip.cn 66免费代理网
https://www.kuaidaili.com/free/inha 快代理
https://www.xicidaili.com 西刺
http://www.ip3366.net/free/?stype=1 云代理
http://www.iphai.com/free/ng IP海
http://www.goubanjia.com/ 全网代理
http://www.89ip.cn/index.html 89免费代理
http://www.qydaili.com/free/?action=china&page=3 旗云代理

接下来,开始干活。(都是宝贝啊,下面用到的都是西拉代理(免费的))
在这里插入图片描述
在这里插入图片描述
现在考虑到情况使用xpath是最好的选项。现在尝试爬取第一页获取IP并将每一个IP以如下形式加入列表中{‘HTTP’;123.154.14.44.:8888’}
在这里插入图片描述

现在效果不错。在优化一下。

初步整合

1.目前还只是获取了Ip代理中的第一页。
2.只是确定方案可行即不再需要等待一分钟左右便可以使得访问量增加。因为这里是多个不同ip访问的模拟多个用户访问,不再是一个用户。
3.由于IP代理中的质量参差不齐(毕竟是免费的么)可能会导致测试是访问异常。
现在代码如下;

import re
import requests
from requests import RequestException
import time
import random
from lxml import etree

def get_ip():
##
    headers_ = {
    
    'User-Agent': 'Mozilla/5.0 '
                             '(Windows NT 10.0; Win64; x64)'
                             ' AppleWebKit/537.36 (KHTML, like Gecko)'
                             ' Chrome/68.0.3440.75 Safari/537.36'}
    url_get = 'http://www.xiladaili.com/gaoni/1/'
    html_ = requests.get(url=url_get, headers=headers)
    html = html_.content.decode('utf-8')
    html_get = etree.HTML(html)
    # 获取代理的请求方式是HTTP还是HTTPS或者二者兼容
    get_ip_way = html_get.xpath('''//div[@class="mt-0 mb-2 table-responsive"]//tbody//tr//td[2]/text()''')
    # 获取IP代理
    get_ip = html_get.xpath('''//div[@class="mt-0 mb-2 table-responsive"]//tbody//tr//td[1]/text()''')
    # print(get_ip_way)
    # print(len(get_ip))
    '''
    对获取的请求方式进行处理,在get_ip_way中的值是这样的;'HTTP代理',或者'HTTP,HTTPS代理’。
    现在去掉中文并将'HTTP,HTTPS代理'改成'HTTP'
    '''
    ip_way = []
    for i in get_ip_way:
        i = i.strip('代理')
        if i == 'HTTP,HTTPS':
            i = 'http'

        i = i.lower()
        ipway.append(i)###

    '''将IP进行整合成字典并加入列表中'''
    ip_list = []
    for i in range(len(ip_way)):
        ip_dict = {
    
    }
        ip_dict[ip_way[i]] = get_ip[i]
        ip_list.append(ip_dict)

    # print(ip_list)
    return ip_list


def get_page(url,proxies):
    proxies=random.choice(proxies)
    try:
        headers = {
    
    
            'Referer': 'https://blog.csdn.net',  # 伪装成从CSDN博客搜索到的文章
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'
        # 伪装成浏览器
        }
        response = requests.get(url, headers=headers,proxies=proxies)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException as e :
        print(e)
        return None


def parse_page(html):
    try:
        '''获取当前博客访问量'''
        read_num = int(re.compile('<span class="read-count">(.*?)</span>').search(html).group(1))
        return read_num
    except Exception:
        print('解析出错')
        return None

def view_page(url,proxies):

    html = get_page(url,proxies)
    if html:
        read_num = parse_page(html)
        if read_num:
            print('当前阅读量:', read_num)

def main():
    proxies=get_ip()
    try:
        while True:
            '''填入待访问的博客下面刷取四个博客访问量'''
            url = 'https://blog.csdn.net/FUTEROX/article/details/107869258'
            view_page(url,proxies)
            url = 'https://blog.csdn.net/FUTEROX/article/details/107869189'
            view_page(url,proxies)
            url = 'https://blog.csdn.net/FUTEROX/article/details/107869159'
            view_page(url,proxies)
            url = 'https://blog.csdn.net/FUTEROX/article/details/107498267'
            view_page(url,proxies)
            sleep_time = random.randint(10, 30)
            print('please wait', sleep_time, 's')
            time.sleep(sleep_time)  # 设置访问频率,过于频繁的访问会触发反爬虫
    except Exception as e:
        print(e)


if __name__ == '__main__':
    main()




效果如下;
在这里插入图片描述

再次整合

升级目标;
1.在第一次整合是Ip地址只获取了一页,此次将获取多次。
2第一次访问时间将不确定可能出现延,需要解决。
3.在原有结构上将IP一一对应比较困难。所以第一次也是使用了随机模块选IP。
4.第一次单线程干活慢,此次多线程处理使用队列处理代码改动将变小。
综上所述,修改如下;

import re
import random
from lxml import etree
import requests
from requests import RequestException
import time
from queue import Queue
ip_queue=Queue(200)
import threading



def get_all_ip():
    url_get='http://www.xiladaili.com/gaoni/{}/'
    x=1
    while True:
        url_get=url_get.format(x)
        x+=1
        try:
            headers = {
    
    'User-Agent': 'Mozilla/5.0 '
                                     '(Windows NT 10.0; Win64; x64)'
                                     ' AppleWebKit/537.36 (KHTML, like Gecko)'
                                     ' Chrome/68.0.3440.75 Safari/537.36'}

            html = requests.get(url=url_get, headers=headers)###
            html = html.content.decode('utf-8')
            html_get = etree.HTML(html)
            # 获取代理的请求方式是HTTP还是HTTPS或者二者兼容
            get_ip_way = html_get.xpath('''//div[@class="mt-0 mb-2 table-responsive"]//tbody//tr//td[2]/text()''')
            # 获取IP代理
            get_ip = html_get.xpath('''//div[@class="mt-0 mb-2 table-responsive"]//tbody//tr//td[1]/text()''')
            # print(get_ip_way)
            # print(len(get_ip))
            '''
            对获取的请求方式进行处理,在get_ip_way中的值是这样的;'HTTP代理',或者'HTTP,HTTPS代理’。
            现在去掉中文并将'HTTP,HTTPS代理'改成'HTTP'
            '''
            ip_way = []
            for i in get_ip_way:
                i = i.strip('代理')
                if i == 'HTTP,HTTPS':
                    i = 'http'

                i = i.lower()
                ip_way.append(i)

            '''将IP进行整合成字典并加入列表中'''
            # ip_list=[]
            for i in range(len(ip_way)):
                ip_dict = {
    
    }
                ip_dict[ip_way[i]] = get_ip[i]
                # ip_list.append(ip_dict)
                ip_queue.put(ip_dict)

            # print(ip_list)
            # print(ip_queue.get())

        except Exceptio as e: ###
            pass



def view_boke(url):
    while True:
        proxies=ip_queue.get()

        try:
            headers = {
    
    
                'Referer': 'https://blog.csdn.net',  # 伪装成从CSDN博客搜索到的文章
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'
            # 伪装成浏览器
            }
            response = requests.get(url, headers=headers,proxies=proxies)

            if response.status_code == 200:
                html=response.text
                try:
                    '''获取当前博客访问量'''
                    read_num = int(re.compile('<span class="read-count">(.*?)</span>').search(html).group(1))
                    if read_num:
                        print('当前阅读量:', read_num)
                        sleep_time = random.randint(10, 30)
                        print('please wait', sleep_time, 's')
                        time.sleep(sleep_time)

                except Exception:
                        pass

        except RequestException as e :
            print(e)

'''开始创建线程'''


'''生产者创建3个'''
for i in range(3):
    t1 = threading.Thread(target=get_all_ip)
    t1.start()
'''消费者创建6个'''
for i in range(6):
    t2 = threading.Thread(target=view_boke, args=['https://blog.csdn.net/FUTEROX/article/details/107869258'])
    t2.start()

效果如下;
在这里插入图片描述
总体效果不错,毕竟免费代理确实不太靠谱。

最终优化

现在不错了,但是还是不够人性化,不主动终止程序不停,毕竟咱们要求不高访问量刷个几百就好了。多了也没有用都是假的数据。

import re
import random
from lxml import etree
import requests
from requests import RequestException
import time
from queue import Queue
ip_queue=Queue(200)

import threading

read_num=None

def get_all_ip(flag):

    if read_num==flag:
        return

    url_get='http://www.xiladaili.com/gaoni/{}/'
    x=1
    while True:
        url_get=url_get.format(x)
        x+=1
        try:
            headers = {
    
    'User-Agent': 'Mozilla/5.0 '
                                     '(Windows NT 10.0; Win64; x64)'
                                     ' AppleWebKit/537.36 (KHTML, like Gecko)'
                                     ' Chrome/68.0.3440.75 Safari/537.36'}

            html_ = requests.get(url=url_get, headers=heades)###
            html = html_.content.decode('utf-8')
            html_get = etree.HTML(html)
            # 获取代理的请求方式是HTTP还是HTTPS或者二者兼容
            get_ip_way = html_get.xpath('''//div[@class="mt-0 mb-2 table-responsive"]//tbody//tr//td[2]/text()''')
            # 获取IP代理
            get_ip = html_get.xpath('''//div[@class="mt-0 mb-2 table-responsive"]//tbody//tr//td[1]/text()''')
            # print(get_ip_way)
            # print(len(get_ip))
            '''
            对获取的请求方式进行处理,在get_ip_way中的值是这样的;'HTTP代理',或者'HTTP,HTTPS代理’。
            现在去掉中文并将'HTTP,HTTPS代理'改成'HTTP'
            '''
            ip_way = []
            for i in get_ip_way:
                i = i.strip('代理')
                if i == 'HTTP,HTTPS':
                    i = 'http'

                i = i.lower()
                ip_way.append(i)

            '''将IP进行整合成字典并加入列表中'''
            # ip_list=[]
            for i in range(len(ip_way)):
                ip_dict = {
    
    }
                ip_dict[ip_way[i]] = get_ip[i]
                # ip_list.append(ip_dict)
                ip_queue.put(ip_dict)

            # print(ip_list)
            # print(ip_queue.get())

        except Exception as e:
            pass



def view_oke(url,flag):###
    global read_num

    while True:
        '''flag 目标访问量'''

        proxies=ip_queue.get()

        try:
            headers = {
    
    
                'Referer': 'https://blog.csdn.net',  # 伪装成从CSDN博客搜索到的文章
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'
            # 伪装成浏览器
            }
            response = requests.get(url, headers=headers,proxies=proxies)

            if response.status_code == 200:
                html=response.text
                try:
                    '''获取当前博客访问量'''
                    read_num = int(re.compile('<span class="read-count">(.*?)</span>').search(html).group(1))
                    if read_num:
                        print('当前阅读量:', read_num)
                        sleep_time = random.randint(10, 30)
                        print('please wait', sleep_time, 's')
                        time.sleep(sleep_time)
                    if read_num == flag:
                        return

                except Exception:
                        pass


        except RequestExcption as e :  ###
            print(e)

'''开始创建线程'''


'''生产者创建3个'''
if '__main__'==__name__:
    flag=int(input('请输入你要刷取的目标总访问量:'))
    #url=input('请输入你要刷取的博客网址;')
    url='https://blog.csdn.net/FUTEROX/article/details/107869258'


    for i in range(3):
        t1 = threading.Thread(target=get_all_ip,args=[flag])
        t1.start()
    '''消费者创建6个'''
    for i in range(6):
        t2 = threading.Thread(target=view_boke, args=[url,flag])
        t2.start()

最最后结果如下;
在这里插入图片描述
(来要CTRL+c,CTRL+v 的把最终优化的代码抄一下就好了)

猜你喜欢

转载自blog.csdn.net/FUTEROX/article/details/108176853