简单的python代码改造为多线程案例

来源:互联网 发布:ubuntu 修改系统语言 编辑:程序博客网 时间:2024/05/01 09:49

前几天,自学python写了一个简单的妹子图的爬虫。但是一个线程爬起来实在是太慢了,于是决定改造成多线程。
其实python里面的多线程还是很好用的,只需要几行代码就改成功了。

首先调用,importthreading 包

improt threading

来使用多线程。

之后把原来的代码改造成一个方法
原代码:

headers = {        'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}  ##浏览器请求头(大部分网站没有这个请求头会报错、请务必加上哦)    all_url = 'http://www.mmjpg.com/'  ##开始的URL地址    start_html = requests.get(all_url,                              headers=headers)  ##使用requests中的get方法来获取all_url(就是:http://www.mzitu.com/all这个地址)的内容 headers为上面设置的请求头、请务必参考requests官方文档解释    start_html.encoding='utf-8'    Soup = BeautifulSoup(start_html.text, 'lxml',from_encoding='utf-8',exclude_encodings='gbk')  ##使用BeautifulSoup来解析我们获取到的网页(‘lxml’是指定的解析器 具体请参考官方文档哦)    # <dd><a href="http://www.mmjpg.com/tag/barbie" target="_blank"><img alt="可儿" src="http://img.mmjpg.com/hot/barbie.jpg"/></a></dd>    #div class="subnav"    #div class="current" 下面的 a href    print(Soup)    all_a = Soup.find('div', class_='subnav').find_all('a')     for a in range(page1, page2):        print(a)        href = "http://www.mmjpg.com/home/" + str(a)        tag_html = requests.get(str(href),                                  headers=headers)        tag_html.encoding = 'utf-8'        Soup2 = BeautifulSoup(tag_html.text, 'lxml',from_encoding='utf-8')        tag_all_a = Soup2.find('div', class_='pic').find_all('a')        for a in tag_all_a:            if "<img alt=" in str(a):                title = a.find('img')['alt']                path = str(title)            else:                continue            isExists = os.path.exists(os.path.join("/Users/zhao/Desktop/mmjpg", path))            if not isExists:                #print(u'建了一个名字叫做', path, u'的文件夹!')                os.makedirs(os.path.join("/Users/zhao/Desktop/mmjpg", path))                os.chdir(os.path.join("/Users/zhao/Desktop/mmjpg", path))                  thref = a['href']                if ('http' in thref):                    # print(thref)                    html = requests.get(thref, headers=headers)                      html_Soup = BeautifulSoup(html.text, 'lxml')                      max_span = html_Soup.find('div', class_='page')                    if max_span != None:                        max_span = max_span.find_all('a')[-2].get_text()                          for page in range(1, int(max_span) + 1):                              page_url = thref + '/' + str(page)  ##同上                            img_html = requests.get(page_url, headers=headers)                            img_Soup = BeautifulSoup(img_html.text, 'lxml')                            img_url = img_Soup.find('div', class_='content')                            if img_url != None:                                img_url = img_url.find('img')['src']                                   name = img_url[-9:-4].replace("/", "")                                  img = requests.get(img_url, headers=headers)                                f = open("/Users/zhaozhengyang/Desktop/mmjpg/" + path + "/" + name + '.jpg',                                         'ab')                                  f.write(img.content)                                  f.close()                            else:                                continue

变成

def mmspider(page1 ,page2):    headers = {        'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}  ##浏览器请求头(大部分网站没有这个请求头会报错、请务必加上哦)    all_url = 'http://www.mmjpg.com/'  ##开始的URL地址    start_html = requests.get(all_url,                              headers=headers)  ##使用requests中的get方法来获取all_url(就是:http://www.mzitu.com/all这个地址)的内容 headers为上面设置的请求头、请务必参考requests官方文档解释    start_html.encoding='utf-8'    Soup = BeautifulSoup(start_html.text, 'lxml',from_encoding='utf-8',exclude_encodings='gbk')  ##使用BeautifulSoup来解析我们获取到的网页(‘lxml’是指定的解析器 具体请参考官方文档哦)    # <dd><a href="http://www.mmjpg.com/tag/barbie" target="_blank"><img alt="可儿" src="http://img.mmjpg.com/hot/barbie.jpg"/></a></dd>    #div class="subnav"    #div class="current" 下面的 a href    print(Soup)    all_a = Soup.find('div', class_='subnav').find_all('a')     for a in range(page1, page2):        print(a)        href = "http://www.mmjpg.com/home/" + str(a)        tag_html = requests.get(str(href),                                  headers=headers)        tag_html.encoding = 'utf-8'        Soup2 = BeautifulSoup(tag_html.text, 'lxml',from_encoding='utf-8')        tag_all_a = Soup2.find('div', class_='pic').find_all('a')        for a in tag_all_a:            if "<img alt=" in str(a):                title = a.find('img')['alt']                path = str(title)            else:                continue            isExists = os.path.exists(os.path.join("/Users/zhao/Desktop/mmjpg", path))            if not isExists:                #print(u'建了一个名字叫做', path, u'的文件夹!')                os.makedirs(os.path.join("/Users/zhao/Desktop/mmjpg", path))                os.chdir(os.path.join("/Users/zhao/Desktop/mmjpg", path))                  thref = a['href']                if ('http' in thref):                    # print(thref)                    html = requests.get(thref, headers=headers)                      html_Soup = BeautifulSoup(html.text, 'lxml')                      max_span = html_Soup.find('div', class_='page')                    if max_span != None:                        max_span = max_span.find_all('a')[-2].get_text()                          for page in range(1, int(max_span) + 1):                              page_url = thref + '/' + str(page)  ##同上                            img_html = requests.get(page_url, headers=headers)                            img_Soup = BeautifulSoup(img_html.text, 'lxml')                            img_url = img_Soup.find('div', class_='content')                            if img_url != None:                                img_url = img_url.find('img')['src']                                   name = img_url[-9:-4].replace("/", "")                                  img = requests.get(img_url, headers=headers)                                f = open("/Users/zhaozhengyang/Desktop/mmjpg/" + path + "/" + name + '.jpg',                                         'ab')                                  f.write(img.content)                                  f.close()                            else:                                continue

然后,建立一个thread数组,并把方法加入数组,后面传入需要的参数。

pages = [10,20,30,40,50,60]threads = []    for page in pages:        t=threading.Thread(target=mmspider, args=(page,page+10))        threads.append(t)

我的第一个参数,是方法名,后一个参数是传入的页码。

最后建立主函数,调用threads。开始执行。

if __name__ == '__main__':    for t in threads:        #t.setDaemon(True)        t.start()

因为是一个爬虫代码,所以遇到了因为访问速度过快,所以经常会被拒绝访问,导致线程崩溃,于是我有开始寻求,线程崩溃后重启的办法。

首先需要定义一个方法,定期自动检测线程是否都存活,如果有线程死亡,则重启。

def checkThread(sleeptimes=60,initThreadsName=[]):    for i in range(0,10080):#循环运行        nowThreadsName=[]#用来保存当前线程名称        now=threading.enumerate()#获取当前线程名        for i in now:            nowThreadsName.append(i.getName())#保存当前线程名称        for page in initThreadsName:            if  page in nowThreadsName:                pass #当前某线程名包含在初始化线程组中,可以认为线程仍在运行            else:                print('==='+page,'stopped,now restart')                t=threading.Thread(target=mmspider(),args=(page))#重启线程                t.setName(page)#重设name                t.start()        time.sleep(sleeptimes)#隔一段时间重新运行,检测有没有线程down

之后修改主函数,在初始化的时候增加一个储存进程名字且统计线程名字的代码

initThreadsName=[]if __name__ == '__main__':    for page in pages:        t=threading.Thread(target=mmspider, args=(page,page+10))        t.setName(page)        threads.append(t)    for t in threads:        #t.setDaemon(True)        t.start()    init = threading.enumerate()  # 获取初始化的线程对象    for i in init:        initThreadsName.append(i.getName())  # 保存初始化线程组名字    check = threading.Thread(target=checkThread, args=(60, initThreadsName))  # 用来检测是否有线程down并重启down线程    check.setName('Thread:check')    check.start()

终于可以快速自动的爬图片啦~

原创粉丝点击