多线程爬取学校维修网站

之前写过一个简单版本的多线程,这次在简单的实战一下多线程,体现多线程的优势。
这次爬虫的目标是中南财经政法大学的校园维修网站,学校寝室或者教学楼出故障了,需要通过维修网站来填报维修信息。
页面信息如下


多线程爬取学校维修网站_第1张图片
i最后一页.png

多线程爬取学校维修网站_第2张图片
页面详情.png

多线程爬取学校维修网站_第3张图片
post提交内容.png

此次爬虫主要分为三个部分:

  • 第一个部分:由于总共有2400多页,需要获取每一条详细的信息,因此,需要一个线程获取每条维修信息对应的url链接。
  • 第二个部分:则是爬虫的解析部分,通过解析每一条页面的信息,提取所需内容。
  • 第三个部分:将提取的信息,按照顺序写入Excel文件中。

第一部分

由于获取页面信息需要通过post的方式获取,get_value是为了获取post里的data的值。get_page是返回post提交以后的页面,get_url则是对页面进行解析,获取每条链接对应的url,并将其存入que中。

import requests
import queue
import time
import threading

url='http://repol.zuel.edu.cn/bxlist.aspx'

que=queue.Queue()

def get_value():
    row_urllist=[] 
    html=requests.get(url).content.decode('utf-8')
    select=etree.HTML(html)
    ll=select.xpath('//input[@name="__VIEWSTATE"]/@value')
    return ll[0]

def get_page(num):
    value=get_value()
    d={
    '__EVENTTARGET':'AspNetPager1',
    '__EVENTARGUMENT': num,
    '__VIEWSTATE':value
    }
    html=requests.post(url,data=d).content.decode('utf-8')
    return (html)

def get_url():
    for i in range(2468):
        html=get_page(i+1)
        select=etree.HTML(html)
        ll=select.xpath('//ul/table/tbody/tr/@onclick')
        for each in ll:
            code=each[-34:-2]
            next_url=r'http://repol.zuel.edu.cn/bxxxcont.aspx?mid='
            new_url=next_url+code
            que.put(new_url)
        print('page',i,'finish')

第二部分

由于已经有了每条维修链接,直接对其进行解析即可。通过get方法得到url,再将解析出的内容写入con中

con=queue.Queue()
def get_content():
    global que
    while True:
        if not que.empty() :
            url=que.get()
            html=requests.get(url).content.decode('utf-8')
            xpat='//table/tr/td/text()'
            select=etree.HTML(html)
            ll=select.xpath(xpat)
            ll=map(lambda x : x.replace('\r\n','').replace(' ',''),ll)
            print('put')
            con.put(list(ll))
        else:
            break

第三部分

所需写入的文件信息都在con中,只需提取并写入Excel中即可。但由于网页的解析速度要远慢于Excel的写入速度,因此在里面讲了count这个变量来检验con是否还在继续运行写入,若4.5秒后count已经不再写入了,则该部分也结束运行。

def write_excel():
    workbook = xlwt.Workbook(encoding='utf-8',style_compression=0)
    sheet = workbook.add_sheet("data1",cell_overwrite_ok = True)
    hang=1
    count=0
    while True:       
        if con.empty() :
            print('sleep ')
            time.sleep(1.5)
            count=count+1
        else:
            data=con.get()
            m=0
            l=0
            while m3:
            print('线程结束')
            break
    workbook.save('weixiu.xls')

最后线程工作

if __name__ == '__main__':
    t1=threading.Thread(target=get_url)
    t1.start()
    time.sleep(2)
    t2=threading.Thread(target=get_content)
    t2.start()    
    t3=threading.Thread(target=get_content)
    t3.start()
    time.sleep(3)
    t4=threading.Thread(target=write_excel)
    t4.start()

运行总共花了1713.7秒


多线程爬取学校维修网站_第4张图片
所花时间.png

多线程爬取学校维修网站_第5张图片
效果图.png

对比

最后本着体现多线程的好处,对比了下单线程和多线程所需的时间,但由于爬取页面过多,因此,将页面减少到50页,多线程总共花费了41.5秒。而单线程则花费了87秒。足足花了一倍多的时间,如果爬取页面数量增加,多线程确实能极大提高爬虫效率。


多线程爬取学校维修网站_第6张图片
多线程.png

多线程爬取学校维修网站_第7张图片
单线程.png

你可能感兴趣的:(多线程爬取学校维修网站)