Python爬虫:教你如何快速提高博文访问量

前言

  免责声明:
    本篇博文所涉及的内容仅供学习,请勿将其用于非法用途!!!

在这里插入图片描述
  本篇博文的初衷是搭建IP池,顺便提高一下博文的访问量,以增加博文的权重,这样就能更大几率获得推荐的机会,让更多对爬虫感兴趣的小伙伴们能够学习到一些知识。
  OK,进入正题。做爬虫的时候,难免会快速多次地访问某个网站,这样就会触发网站的反爬虫机制,一段时间内网站会拒绝来自此IP的访问请求,即所谓的“封IP”。我们可以通过代理软件,将本机的IP伪装成另一个IP,然后再向网站发起请求,这样网站就不会发现本机的真实IP了。
  所以,本篇博客就是搭建这样一个伪IP池,通过代理程序去访问网站。大致流程就是:

  爬取代理IP > -> 测试IP > -> 保存IP

在这里插入图片描述
  下面几个网站提供的IP都是免费的,但请不要过分爬取

1. 66IP代理

  66ip代理网站的主页面是这样的,通过几次点击发现:每个省份之间的URL是相似的,注意观察下面两幅图所标记处。

在这里插入图片描述
在这里插入图片描述
  想必你已经发现了,没错,areaindex_1就是北京的ip,areaindex_10就是江苏的ip,既然URL的构造规律我们已经知道了,下面来分析一下如何从HTML界面中获取想要的ip和port。
  打开Google Chrome的调试界面,F5刷新界面,选择一个ip来看一下:

在这里插入图片描述
  每一条信息都在一个tr标签里,即表table标签里的一行,td标签是表示一列,他们都属于HTML里面的内容,这里不再过多叙述。既然对爬虫感兴趣,那么与Web网页有关的HTML、CSS、JavaScript等知识肯定是要有的。
  下面就通过requests库来获取HTML的页面内容,然后通过BeautifulSoup库解析我们想要获取的内容。大致流程就是:先定位到tr标签,然后获取tr标签里前两个td标签里的内容,然后用pickle库保存获取的ip,代码如下:

def get_html(url, flag=True):
    try:
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                                 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        if flag:
            response.encoding = 'utf-8'
        else:
            response.encoding = 'gb2312'
        return response.text
    except Exception as err:
        return '请求异常'


def get_66ip():
    ip_list = []
    for index in range(1, 35):
        count = 0
        province = ''
        url = 'http://www.66ip.cn/areaindex_{}/1.html'.format(index)
        html = get_html(url, flag=False)
        soup = BeautifulSoup(html, 'lxml')
        tr_list = soup.find_all(name='tr')
        for tr_ in tr_list[2:]:
            td_list = tr_.find_all(name='td')
            ip = td_list[0].string
            port = td_list[1].string
            province = td_list[2].string
            ip_port = ip + ':' + port
            ip_list.append(ip_port)
            count += 1
        print('Saved {0} {1} ip.'.format(province, count))
        # 速度不要太快哦!, 否则获取不到页面内容
        time.sleep(3)
    with open('./ip/66ip.pickle', 'wb') as f:
        pickle.dump(ip_list, f)

    print('Finished!!!')
    

  每个网站的网页编码方式可能不一样,有些是gb2312,有些是utf-8,注意查看网站meta标签 ( ( 一般位于网站源码的最前面 ) ) 里的charset属性是什么,否则内容返回的是乱码。

2. 开心代理

  开心代理网站的主页面是这样的,通过几次点击发现:下面按钮所对应的每个页面之间的URL也是相似的,注意观察下面两幅图所标记处。

在这里插入图片描述
在这里插入图片描述
  没错,1.html就是第1页,8.html就是第8页,既然URL的构造规律我们已经知道了,下面来分析一下如何从HTML界面中获取想要的ip和port。
  方法和上面的一样:

在这里插入图片描述
  enmmm,和上面那个网站的方式一毛一样,代码也是一样的,代码如下:

def get_kaixinip():
    ip_list = []
    for index in range(1, 9):
        count = 0
        url = 'http://www.kxdaili.com/dailiip/1/{}.html'.format(index)
        html = get_html(url)
        soup = BeautifulSoup(html, 'lxml')
        tr_list = soup.find_all(name='tr')
        for tr_ in tr_list[2:]:
            td_list = tr_.find_all(name='td')
            ip = td_list[0].string
            port = td_list[1].string
            ip_port = ip + ':' + port
            ip_list.append(ip_port)
            count += 1
        print('Saved {0} page {1} ip.'.format(index, count))
        # 速度不要太快哦!, 否则获取不到页面内容
        time.sleep(3)

    with open('./ip/kaixinip.pickle', 'wb') as f:
        pickle.dump(ip_list, f)

    print('Finished!!!')
    

3. 全网代理

  全网代理网站的主页面是这样的,该网站只免费提供了10个ip,可以爬取下来试一下。

在这里插入图片描述
  注意看哦,和上面的有点不同哦,虽然元素都是一样的,但是这个网站采取了反爬虫措施,很明显是一个CSS反爬,因为style="display: none;"所修饰的内容在网页上是不显示的,放在代码里主要是迷惑咱们,这属于CSS的内容,感兴趣的可以了解一下。
  下面要做的其实是和上面一样的,只不过是要过滤的style="display: none;"所修饰的标签,然后拼成咱们需要的ip,代码如下:

def get_goubanjiaip():
    ip_list = []
    url = 'http://www.goubanjia.com/'
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    td_list = soup.find_all(class_='ip')
    for td_ in td_list:
        ip_ = ''
        for child in td_.children:
            if child == ':':
                ip_ += child
            elif not child.attrs:
                ip_ += child.get_text()
            elif list(child.attrs.keys())[0] == 'class':
                ip_ = ip_ + child.get_text()
            elif child.attrs['style'] == 'display:inline-block;' or child.attrs['style'] == 'display: inline-block;':
                ip_ += child.get_text()
        ip_list.append(ip_)

    with open('./ip/goubanjiaip.pickle', 'wb') as f:
        pickle.dump(ip_list, f)

    print('Finished!!!')
    

4. 快代理

  快代理网站的主页面是这样的,你会发现其实和开心代理一毛一样,这里就不过多说明了。

在这里插入图片描述

在这里插入图片描述
  代码如下:

def get_kuaidaili():
    ip_list = []
    for index in range(1, 100):
        count = 0
        url = 'https://www.kuaidaili.com/free/inha/{}/'.format(index)
        html = get_html(url)
        soup = BeautifulSoup(html, 'lxml')
        tr_list = soup.find_all(name='tr')
        for tr_ in tr_list[1:]:
            td_list = tr_.find_all(name='td')
            ip = td_list[0].string
            port = td_list[1].string
            ip_port = ip + ':' + port
            ip_list.append(ip_port)
            count += 1
        print('Saved {0} page {1} ip.'.format(index, count))
        # 速度不要太快哦!, 否则获取不到页面内容
        time.sleep(3)

    with open('./ip/kuaidaili.pickle', 'wb') as f:
        pickle.dump(ip_list, f)

    print('Finished!!!')
    

5. 异步测试

  采用aiohttp库,结合asyncio库进行异步测试。这里不采用requests库是因为它是一个阻塞式的HTTP请求库,简单说就是当我们发起一个请求后,程序会一直等待服务器响应,直到得到响应后,程序才会进行下一步操作。如果服务器不响应,它就会一直等待,直到超时,这样会耗费大量的时间,尤其是成千上万个ip需要测试时。所以,我们想要让程序在等待响应的时候去做其他的事情,比如继续发起新的请求。
  而aiohttp库就是这样能提供异步Web服务的HTTP库,单个ip测试代码如下:

async def test_ip(ip_, url):
    global ip_ok
    conn = aiohttp.TCPConnector(verify_ssl=False)
    async with aiohttp.ClientSession(connector=conn) as session:
        try:
            proxy_ip = 'http://' + ip_
            print('正在测试: ' + proxy_ip)
            async with session.get(url=url, headers=headers, proxy=proxy_ip, timeout=15) as response:
                if response.status == 200:
                    print('代理可用: ' + ip_)
                    ip_ok.append(ip_)
                else:
                    print('请求响应码不合法 ' + ip_)
        except:
            print('代理请求失败', ip_)
            

  总的程序流程代码如下:

if __name__ == '__main__':
    url = 'https://blog.csdn.net/qq_42730750/article/details/107585866'
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                             'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
    
    get_66ip()
    get_kaixinip()
    get_goubanjiaip()
    get_kuaidaili()
    
    with open('./ip/66ip.pickle', 'rb') as f1:
        ip_list1 = pickle.load(f1)
        ip_list1 = list(set(ip_list1))
    with open('./ip/kaixinip.pickle', 'rb') as f2:
        ip_list2 = pickle.load(f2)
        ip_list2 = list(set(ip_list2))
    with open('./ip/goubanjiaip.pickle', 'rb') as f3:
        ip_list3 = pickle.load(f3)
        ip_list3 = list(set(ip_list3))
    with open('./ip/kuaidaili.pickle', 'rb') as f4:
        ip_list4 = pickle.load(f4)
    ip_list = ip_list1 + ip_list2 + ip_list3 + ip_list4
    
    ip_ok = []
    print('开始测试: ')
    try:
        loop = asyncio.get_event_loop()
        for i in range(0, len(ip_list), 10):
            proxies_ip = ip_list[i: i+10]
            tasks = [test_ip(proxy_ip, url) for proxy_ip in proxies_ip]
            loop.run_until_complete(asyncio.wait(tasks))
            time.sleep(5)
    except Exception as err:
        print('发生错误:', err.args)
    
    with open('./ip/all_ip_ok.pickle', 'wb') as f_:
        pickle.dump(ip_ok, f_)
    

  结果如下:

在这里插入图片描述

结束语

  本篇爬取的IP都来自免费的代理网站提供的,所以能用的IP数较低,如果需要更高质量的IP,可以购买付费的IP以供使用。另外,再次提醒:即使有了代理池,也不要太频繁的访问某个网站,更不要去获取敏感非法信息。

  文明爬虫,从我做起!!!

猜你喜欢

转载自blog.csdn.net/qq_42730750/article/details/107703589