使用线程池多线程爬取链接,检验链接正确性

我们网站大多数链接都是活链接都是运营配置的,而有的时候运营会将链接配置错误使访问出错,有时也会因为程序bug造成访问出错,因此对主站写了个监控脚本,使用python爬取主站设置的链接并访问,统计访问出错的链接,因为链接有上百个,所以使用了多线程进行,因为http访问是io密集型,所以python多线程还是可以很好的完成并发访问的。

首先是index.py

使用了线程池管理线程,做到了配置需要检验的链接,然后爬取配置的链接页面中的所有链接,同时因为可能子页面许多url链接是和主站重复的,也可以做剔除

配置文件使用了yml文件:  is_checkIndex  是否检查与首页重复,如果为True,则剔除和首页重复的url

爬取链接使用了requests和正则表达式

最后是统计出错的链接,在这里也做了筛选,只筛选与网站相关的url,像一些合作网站等广告链接是不会记录返回

# encoding=utf-8
from queue import Queue
import queue
from Tool.hrefTool import HrefTest
import threading
import time
from Tool.Log.logTool import LogTool

index_url = ‘https://bj.jiehun.com.cn‘

class HunIndex:
    def __init__(self, url, is_checkIndex, index_items):
        self.url_queue = Queue()
        self.headers = {
            ‘User-Agent‘: ‘Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6‘,
        }
        self.thread_stop = False
        self.items = HrefTest.get_hostsit_href(url, self.headers)
        if is_checkIndex:
            self.index_items = index_items
        self.start_time = time.time()
        self.stop_time = None
        self.error_list = []
        self.url = url
        self.is_checkIndex = is_checkIndex
        self.execute_items = []

    def get_index_urlitem(self):
        LogTool.info(‘开始获取页面url,当前页面:{url}‘.format(url=self.url))
        if self.is_checkIndex:
            self.execute_items.extend([item for item in self.items if item not in self.index_items])
        else:
            self.execute_items.extend(self.items)
        for item in list(set(self.execute_items)):
            if HrefTest.check_url(item[0]):
               item1 = (HrefTest.change_url(item[0], index_url), item[1])
               self.url_queue.put(item1, block=True, timeout=5)
        LogTool.info(‘页面url获取完成,共{sum_url}个url‘.format(sum_url=self.url_queue.qsize()))

    def _parse_url(self, item):
        try:
            LogTool.info(‘检查url: %s, 标题:%s‘ % (str(item[0]), str(item[1])))
            response = HrefTest.get(item[0], self.headers)
        except Exception as e:
            LogTool.error(‘请求失败,url=%s, error_messge:%s‘ % (str(item[0]), e))
            print(‘error-%s, message-%s‘ % (item[0], e))
            error = list(item)
            print(‘error‘, list(item))
            error.append(‘error_message=%s‘ % e)
            self.error_list.append(error)
        else:
            if not response.status_code == 200:
                LogTool.error(‘请求失败,url=%s, error_code:%s‘ % (str(item[0]), response.status_code))
                print(‘error-%s error_code:%s‘ % (item[0], response.status_code))
                error = list(item).append(‘error_message=%s‘ % response.status_code)
                print(‘error‘, item)
                print(‘----‘, error)
                self.error_list.append(error)
            else:
                LogTool.info(‘请求成功,测试通过,url=%s,title=%s‘ % (str(item[0]), str(item[1])))
                print(‘success-%s‘ % item[0])
                pass

    def parse_url(self):
        while not self.thread_stop:
            try:
                item = self.url_queue.get(timeout=5)
            except queue.Empty:
                self.thread_stop = True
                break
            self._parse_url(item)
            self.url_queue.task_done()

    def run(self):
        thread_list = []
        t_url = threading.Thread(target=self.get_index_urlitem)
        thread_list.append(t_url)
        for i in range(35):
            t_parse = threading.Thread(target=self.parse_url)
            thread_list.append(t_parse)
        for t in thread_list:
            t.setDaemon(True)
            t.start()
        for q in [self.url_queue]:
            q.join()
        self.stop_time = time.time()

if __name__ == ‘__main__‘:
    page_url = ‘https://bj.jiehun.com.cn/hunshasheying/storelists?source=BJIndexFL_1_1&ordersrc=BJIndexFL_1_1‘
    hun = HunIndex(page_url, True)
    hun.run()
    sum_time = int(hun.stop_time - hun.start_time)
    print(sum_time)

爬取链接:

    def get_hostsit_href(cls, url, headers):
        ‘‘‘
           获取url页面所有href a标签
        :param url:       要抓取的url
        :param headers:   请求头
        :return:          所有符合的url 及标题
        ‘‘‘
        try:
            response = requests.request(‘GET‘, url=url, headers=headers)
        except Exception as e:
            print(‘error-{url}    message-{e}‘.format(url=url, e=e))
        else:
            # print(response.text)
            # pattern = re.compile(‘<a.*href="(.*?)".{0}=?"?.*"?>(.*?)</a>‘)
            pattern = re.compile(‘href="(.*?)"{1}.?.{0,10}?=?"?.*"?>(.+)?</a>‘)
            # pattern = re.compile(‘<a\b[^>]+\bhref="([^"]*)"[^>]*>([\s\S]*?)</a>‘)
            items = re.findall(pattern, response.text)
            return items

比较简单  正则写的不是很匹配,但是已经能匹配出90%以上的链接,完全满足需求了,因为对这方面还不是很熟悉,还有待学习。

效果:

因为链接访问,即使多线程也要看网速等影响因素,网速好首页300多个链接用时20秒左右,不好要40来秒,作为日常检测还是可以的,如果检测我们网站主站所有主频道页面,基本在10分钟内可以完成,但是如果要是完成分城市站的所有监控那就有点鸡肋了,写过一级链接检测完接着检测二级链接的,用了半个多小时,4万多个链接,有点过分了。。,并且有的链接可能只是id不同,并没有很大的实际意义(例如商品类的url只是id不同,那这类检测在这4万多个中可能就有很多个重复的类似链接),后续看如何优化。。

时间: 2024-08-24 15:27:27

使用线程池多线程爬取链接,检验链接正确性的相关文章

多线程爬取百度百科

前言:EVERNOTE里的一篇笔记,我用了三个博客才学完...真的很菜...百度百科和故事网并没有太过不一样,修改下编码,debug下,就可以爬下来了,不过应该是我爬的东西太初级了,而且我爬到3000多条链接时,好像被拒绝了...爬取速度也很慢,估计之后要接触一些优化或者多进程,毕竟python是假的多线程.本博客参照代码及PROJECT来源:http://kexue.fm/archives/4385/ 源代码: 1 #! -*- coding:utf-8 -*- 2 import reques

Python爬虫入门教程: All IT eBooks多线程爬取

All IT eBooks多线程爬取-写在前面 对一个爬虫爱好者来说,或多或少都有这么一点点的收集癖 ~ 发现好的图片,发现好的书籍,发现各种能存放在电脑上的东西,都喜欢把它批量的爬取下来. 然后放着,是的,就这么放着.......然后慢慢的遗忘掉..... All IT eBooks多线程爬取-爬虫分析 打开网址 http://www.allitebooks.com/ 发现特别清晰的小页面,一看就好爬 在点击一本图书进入,发现下载的小链接也很明显的展示在了我们面前,小激动一把,这么清晰无广告的

多线程爬取小说时如何保证章节的顺序

前言 爬取小说时,以每一个章节为一个线程进行爬取,如果不加以控制的话,保存的时候各个章节之间的顺序会乱掉. 当然,这里说的是一本小说保存为单个txt文件,如果以每个章节为一个txt文件,自然不会存在这种情况. 不仅仅是小说,一些其他的数据在多线程爬取时也有类似情况,比如: 漫画:漫画其实是由大量图片组成,一般一本漫画会保存为一个pdf文件,在此过程要保证图片的顺序. 视频:现在网络上的视频大部分是由多个ts文件拼合,最后保存为一个mp4文件,要保证ts文件的顺序. 它们都有一个共同的特点,那就是

实现多线程爬取数据并保存到mongodb

多线程爬取二手房网页并将数据保存到mongodb的代码: import pymongo import threading import time from lxml import etree import requests from queue import Queue index_url='https://m.lianjia.com/gz/ershoufang/pg{}/' detail_url='https://m.lianjia.com{}' # 设置爬取主页的页数 INDEX_PAGE_

python多线程爬取网页

#-*- encoding:utf8 -*- ''' Created on 2018年12月25日 @author: Administrator ''' from multiprocessing.dummy import Pool as pl import csv import requests from lxml import etree def spider(url): header = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1

多线程爬取糗事百科热门段子 (改写前天的博客)

利用多线程爬取,除了先前用到的几个模块之外,还需用到threading模块和queue模块: 为每一件事情开启一个线程:构造url_list.发送请求.提取数据.保存数据 __init__方法添加三个实例属性队列分别存放:url.响应内容.处理后的数据 改写原先每一个方法里的代码,需要的东西直接从队列中取出,此时方法都无需多余参数了 每当从一个队列取出数据,记得执行task_done()方法,使计数减一 run()方法里把yaozhixing的事情都开启一个线程,比较慢的事情,比如网络请求,可以

多线程爬取笔趣阁免费小说全站爬取

import threading,os,time,requests,pymongo,refrom queue import Queuefrom lxml import etreefrom bs4 import BeautifulSoup as BPclient = pymongo.MongoClient(host='localhost',port=27017)mg = client['biquge']def get_fenlei(): """ 爬取图书全部分类 :return

【Python3 爬虫】U28_多线程爬取斗图啦的表情包

目录 1.需求描述 2.实战代码 2.1 单线程爬取 2.2 多线程版 1.需求描述 爬取斗图啦网站,地址为:https://www.doutula.com/photo/list/[Python3 爬虫]U28_多线程爬取斗图啦的表情包 原文地址:https://www.cnblogs.com/OliverQin/p/12636681.html

网络爬虫:使用多线程爬取网页链接

前言: 经过前面两篇文章,你想大家应该已经知道网络爬虫是怎么一回事了.这篇文章会在之前做过的事情上做一些改进,以及说明之前的做法的不足之处. 思路分析: 1.逻辑结构图 上图中展示的就是我们网络爬虫中的整个逻辑思路(调用Python解析URL,这里仅仅作了简略的展示). 2.思路说明: 首先.我们来把之前思路梳理一下.之前我们採用的两个队列Queue来保存已经訪问过和待訪问的链接列表,并採用广度优先搜索进行递归訪问这些待訪问的链接地址.并且这里使用的是单线程操作. 在对数据库的操作中.我们加入了