亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python 實(shí)現(xiàn)堆排序

系統(tǒng) 2152 0

上一關(guān),我們學(xué)習(xí)了Scrapy框架,知道了Scrapy爬蟲公司的結(jié)構(gòu)和工作原理。
python爬蟲第14關(guān)Scrapy實(shí)操_第1張圖片
在Scrapy爬蟲公司里,引擎是最大的boss,統(tǒng)領(lǐng)著調(diào)度器、下載器、爬蟲和數(shù)據(jù)管道四大部門。

這四大部門都聽命于引擎,視引擎的需求為最高需求。
python爬蟲第14關(guān)Scrapy實(shí)操_第2張圖片
我們還通過實(shí)操爬取豆瓣Top250圖書的項(xiàng)目,熟悉了Scrapy的用法。

python爬蟲第14關(guān)Scrapy實(shí)操_第3張圖片
這一關(guān),我會帶你實(shí)操一個(gè)更大的項(xiàng)目——用Scrapy爬取招聘網(wǎng)站的招聘信息。

你可以借此體驗(yàn)一把當(dāng)Scrapy爬蟲公司CEO的感覺,用代碼控制并操作整個(gè)Scrapy的運(yùn)行。

那我們爬取什么招聘網(wǎng)站呢?在眾多招聘網(wǎng)站中,我挑選了職友集。這個(gè)網(wǎng)站可以通過索引的方式,搜索到全國上百家招聘網(wǎng)站的最新職位。

https://www.jobui.com/rank/company/

我們先對這個(gè)網(wǎng)站做初步的觀察,這樣我們才能明確項(xiàng)目的爬取目標(biāo)。

明確目標(biāo)

打開網(wǎng)址后,你會發(fā)現(xiàn):這是職友集網(wǎng)站的地區(qū)企業(yè)排行榜,里面含有本月人氣企業(yè)榜、最佳口碑雇主、最多粉絲企業(yè)榜和最多評論企業(yè)榜四個(gè)榜單。

python爬蟲第14關(guān)Scrapy實(shí)操_第4張圖片
點(diǎn)擊【北京字節(jié)跳動(dòng)科技有限公司】,會跳轉(zhuǎn)到這家公司的詳情頁面,再點(diǎn)擊【招聘】,就能看到這家公司正在招聘的所有崗位信息。
python爬蟲第14關(guān)Scrapy實(shí)操_第5張圖片
初步觀察后,我們可以把爬取目標(biāo)定為:先爬取企業(yè)排行榜四個(gè)榜單里的公司,再接著爬取這些公司的招聘信息。

每個(gè)榜單有10家公司,四個(gè)榜單一共就是40家公司。也就是說,我們要先從企業(yè)排行榜爬取到這40家公司,再跳轉(zhuǎn)到這40家公司的招聘信息頁面,爬取到公司名稱、職位、工作地點(diǎn)和招聘要求。

分析過程

明確完目標(biāo),我們開始分析過程。首先,要看企業(yè)排行榜里的公司信息藏在了哪里。

企業(yè)排行榜的公司信息

請你右擊打開“檢查”工具,點(diǎn)擊Network,刷新頁面。點(diǎn)開第0個(gè)請求company/,看Response,找一下有沒有榜單的公司信息在里面。

python爬蟲第14關(guān)Scrapy實(shí)操_第6張圖片
一找,發(fā)現(xiàn)四個(gè)榜單的所有公司信息都在里面。說明企業(yè)排行榜的公司信息就藏在html里。

現(xiàn)在請你點(diǎn)擊Elements,點(diǎn)亮光標(biāo),再把鼠標(biāo)移到【北京字節(jié)跳動(dòng)科技有限公司】,這時(shí)就會定位到含有這家公司信息的元素上。
python爬蟲第14關(guān)Scrapy實(shí)操_第7張圖片
點(diǎn)擊href="/company/10375749/",會跳轉(zhuǎn)到字節(jié)跳動(dòng)這家公司的詳情頁面。詳情頁面的網(wǎng)址是:
https://www.jobui.com/company/10375749/
你再把鼠標(biāo)移到【阿里巴巴集團(tuán)】,點(diǎn)擊href="/company/281097/",會跳轉(zhuǎn)到阿里公司的詳情頁面,頁面的網(wǎng)址為:

https://www.jobui.com/company/281097/

我們可以猜到:/company/+數(shù)字/應(yīng)該是公司id的標(biāo)識。這么一觀察,榜單上的公司詳情頁面的網(wǎng)址規(guī)律我們就得出來了。
python爬蟲第14關(guān)Scrapy實(shí)操_第8張圖片
那么,我們只要把元素的href屬性的值提取出來,就能構(gòu)造出每家公司詳情頁面的網(wǎng)址。

構(gòu)造公司詳情頁面的網(wǎng)址是為了后面能獲得詳情頁面里的招聘信息。

現(xiàn)在,我們來分析html的結(jié)構(gòu),看看怎樣才能把元素href屬性的值提取出來。
python爬蟲第14關(guān)Scrapy實(shí)操_第9張圖片
仔細(xì)觀察html的結(jié)構(gòu),你會發(fā)現(xiàn),每個(gè)公司信息都藏在一個(gè)

  • 元素里,而每5個(gè)
  • 元素都從屬與一個(gè)
      標(biāo)簽。這是一個(gè)層層嵌套的關(guān)系。
  • 我們想拿到所有元素href屬性的值。我們當(dāng)然不能直接用find_all()抓取標(biāo)簽,原因也很簡單:這個(gè)頁面有太多的標(biāo)簽,會抓出來很多我們不想要的信息。

    一個(gè)穩(wěn)妥的方案是:先抓取最外層的

      標(biāo)簽,再抓取
        標(biāo)簽里的 元素,最后提取到 元素href屬性的值。就像剝洋蔥,要從最外面的一層開始剝一樣。

    這里沒有通過抓

  • 元素來獲取元素href屬性的值,是因?yàn)?
  • 元素沒有class屬性,也沒有id屬性,并不方便我們定位和提取。
  • 分析到這里,我們已經(jīng)知道公司詳情頁面的網(wǎng)址規(guī)律,和如何提取元素href屬性的值。
    接下來,我們需要分析的就是,每家公司的詳情頁面。

    公司詳情頁面的招聘信息

    我們打開【北京字節(jié)跳動(dòng)科技有限公司】的詳情頁面,點(diǎn)擊【招聘】。這時(shí),網(wǎng)址會發(fā)生變化,多了jobs的參數(shù)。

    python爬蟲第14關(guān)Scrapy實(shí)操_第10張圖片
    如果你多點(diǎn)擊幾家公司的詳情頁面,查看招聘信息,就會知道:公司招聘信息的網(wǎng)址規(guī)律也是有規(guī)律的。

    比如,阿里的招聘信息的網(wǎng)址是:

    https://www.jobui.com/company/281097/jobs/

    python爬蟲第14關(guān)Scrapy實(shí)操_第11張圖片
    接著,我們需要找找看公司的招聘信息都存在了哪里。

    還是在字節(jié)跳動(dòng)公司的招聘信息頁面,右擊打開“檢查”工具,點(diǎn)擊Network,刷新頁面。我們點(diǎn)擊第0個(gè)請求jobs/,查看Response,翻找看看里面有沒有這家公司的招聘信息。
    python爬蟲第14關(guān)Scrapy實(shí)操_第12張圖片
    在Response里我們找到了想要的招聘信息。這說明公司的招聘信息依舊是藏在了html里。

    接下來,你應(yīng)該知道要分析什么了吧。

    分析的套路都是相同的,知道數(shù)據(jù)藏在html后,接著是分析html的結(jié)構(gòu),想辦法提取出我們想要的數(shù)據(jù)。

    那就按照慣例點(diǎn)擊Elements,然后點(diǎn)亮光標(biāo),把鼠標(biāo)移到公司名稱吧。
    python爬蟲第14關(guān)Scrapy實(shí)操_第13張圖片
    公司名稱藏在

    標(biāo)簽下的 元素的文本中。按道理來說,我們可以通過class屬性,定位到
    的這個(gè)標(biāo)簽,取出
    標(biāo)簽的文本,就能拿到公司名稱。

    不過經(jīng)過我?guī)状蔚牟僮髟囼?yàn),發(fā)現(xiàn)職友集這個(gè)網(wǎng)站間隔一段時(shí)間就會更換這個(gè)標(biāo)簽的名字(可能你此時(shí)看到的標(biāo)簽名不一定是

    )。

    為了保證一定能取到公司名稱,我們改成用id屬性(id=“companyH1”)來定位這個(gè)標(biāo)簽。這樣,不管這個(gè)標(biāo)簽名字如何更換,我們依舊能抓到它。

    下面,再把鼠標(biāo)移到崗位名稱,看看招聘的崗位信息可以怎么提取。
    python爬蟲第14關(guān)Scrapy實(shí)操_第14張圖片
    你會發(fā)現(xiàn):每個(gè)崗位的信息都藏在一個(gè)

    標(biāo)簽下,職位名稱在元素的文本中,工作地點(diǎn)和職位要求在 div class="job-desc" 的兩個(gè) s pan 元素里。
    python爬蟲第14關(guān)Scrapy實(shí)操_第15張圖片
    這樣分析下來,我們想要的招聘信息,包括公司名稱、職位名稱、工作地點(diǎn)和職位要求,都定位清楚了。
    至此,我們分析完了整個(gè)爬取過程,接下來就是代碼實(shí)現(xiàn)啦。

    代碼實(shí)現(xiàn)
    python爬蟲第14關(guān)Scrapy實(shí)操_第16張圖片
    我們按照Scrapy正常的用法一步步來。首先,我們必須創(chuàng)建一個(gè)Scrapy項(xiàng)目。
    創(chuàng)建項(xiàng)目

    還記得怎么創(chuàng)建嗎?打開本地電腦的終端(windows:Win+R,輸入cmd;mac:command+空格,搜索“終端”),跳轉(zhuǎn)到你想要保存項(xiàng)目的目錄下,輸入創(chuàng)建Scrapy項(xiàng)目的命令:scrapy startproject jobui(jobui是職友集網(wǎng)站的英文名,在這里我們把它作為Scrapy項(xiàng)目的名字)。
    創(chuàng)建好項(xiàng)目后,你在本地電腦的編譯器打開這個(gè)Scrapy項(xiàng)目,會看到如下的結(jié)構(gòu):
    python爬蟲第14關(guān)Scrapy實(shí)操_第17張圖片
    定義item

    我們剛剛分析的時(shí)候,已經(jīng)確定要爬取的數(shù)據(jù)是公司名稱、職位名稱、工作地點(diǎn)和招聘要求。
    那么,現(xiàn)在請你寫出定義item的代碼(提示:要在items.py這個(gè)文件里定義item。

                  
                    import scrapy
    
    class JobuiItem(scrapy.Item):
    #定義了一個(gè)繼承自scrapy.Item的JobuiItem類
        company = scrapy.Field()
        #定義公司名稱的數(shù)據(jù)屬性
        job = scrapy.Field()
        #定義職位名稱的數(shù)據(jù)屬性
        base = scrapy.Field()
        #定義工作地點(diǎn)的數(shù)據(jù)屬性
        detail = scrapy.Field()
        #定義招聘要求的數(shù)據(jù)屬性
    
                  
                

    創(chuàng)建和編寫爬蟲文件

    定義好item,我們接著要做的是在spiders里創(chuàng)建爬蟲文件,命名為jobui_ jobs。
    現(xiàn)在,我們可以開始在這個(gè)爬蟲文件里編寫代碼。

    先導(dǎo)入所需的模塊:

                  
                    import scrapy  
    import bs4
    from ..items import JobuiItem
    
                  
                

    接下來,是編寫爬蟲的核心代碼。我會先帶著你理清代碼的邏輯,這樣等下你才能比較順利地理解和寫出代碼。

    在前面分析過程的步驟里,我們知道要先抓取企業(yè)排行榜40家公司的id標(biāo)識,比如字節(jié)跳動(dòng)公司的id標(biāo)識是/company/10375749/。
    python爬蟲第14關(guān)Scrapy實(shí)操_第18張圖片
    再利用抓取到的公司id標(biāo)識構(gòu)造出每家公司招聘信息的網(wǎng)址。比如,字節(jié)跳動(dòng)公司的招聘信息網(wǎng)址就是https://www.jobui.com+/company/10375749/jobs/

    我們需要再把每家公司招聘信息的網(wǎng)址封裝成requests對象。這里你可能有點(diǎn)不理解為什么要封裝成requests對象,我解釋一下。

    如果我們不是使用Scrapy,而是使用requests庫的話,一般我們得到一個(gè)網(wǎng)址,需要用requests.get(),傳入網(wǎng)址這個(gè)參數(shù),才能獲取到網(wǎng)頁的源代碼。
    python爬蟲第14關(guān)Scrapy實(shí)操_第19張圖片
    而在Scrapy里,獲取網(wǎng)頁源代碼這件事兒,會由引擎交分配給下載器去做,不需要我們自己處理。我們之所以要構(gòu)造新的requests對象,是為了告訴引擎,我們新的請求需要傳入什么參數(shù)。

    這樣才能讓引擎拿到的是正確requests對象,交給下載器處理。

    既然構(gòu)造了新的requests對象,我們就得定義與之匹配的用來處理response的新方法。這樣才能提取出我們想要的招聘信息的數(shù)據(jù)。

    好啦,核心代碼的邏輯我們理清楚了。

    python爬蟲第14關(guān)Scrapy實(shí)操_第20張圖片
    我們接著往下寫核心代碼。

                  
                    import scrapy
    import bs4
    from ..items import JobuiItem
    
    class JobuiSpider(scrapy.Spider):
    #定義一個(gè)爬蟲類JobuiSpider
        name='jobs'
        #定義爬蟲的名字為jobs
        allowed_domains=['www.jobui.com']
        #定義允許爬蟲爬取網(wǎng)址的域名——職友集網(wǎng)站的域名
        start_ulrs=['https://www.jobui.com/rank/company/']
        #定義起始網(wǎng)址——職友集企業(yè)排行榜的網(wǎng)址
    
        def parse(self,response):
        #parse是默認(rèn)處理response的方法
            bs=bs4.BeautifulSoup(response.text,'html.parser')
            #用BeautifulSoup解析response(企業(yè)排行榜的網(wǎng)頁源代碼)
            ur_list=bs.find_all('ul',class_='textList flsty cfix')
            #用find_all提取<'ul' class_='textList flsty cfix'>標(biāo)簽
            for ul in ul_list:
            #遍歷ul_list
                a_list = ul.find_all('a')
                #用find_all提取出
                    
                  
                

    第6-13行代碼:定義了爬蟲類JobuiSpider、爬蟲的名字jobs、允許爬蟲爬取的域名和起始網(wǎng)址。

    剩下的代碼,你應(yīng)該都能看懂。我們用默認(rèn)的parse方法來處理response(企業(yè)排行榜的網(wǎng)頁源代碼);用BeautifulSoup來解析response;用find_all方法提取數(shù)據(jù)(公司id標(biāo)識)。
    python爬蟲第14關(guān)Scrapy實(shí)操_第21張圖片
    公司id標(biāo)識就是元素的href屬性的值,我們想要把它提取出來,就得先抓到所有最外層的

      標(biāo)簽,再從中抓取所有 元素。

    所以這里用了兩個(gè)for循環(huán),把元素的href屬性的值提取了出來,并成功構(gòu)造了公司招聘信息的網(wǎng)址。

    代碼寫到這里,我們已經(jīng)完成了核心代碼邏輯的前兩件事:提取企業(yè)排行榜的公司id標(biāo)識和構(gòu)造公司招聘信息的網(wǎng)址。

    python爬蟲第14關(guān)Scrapy實(shí)操_第22張圖片
    接下來,就是構(gòu)造新的requests對象和定義新的方法處理response。

    繼續(xù)來完善核心代碼(請你重點(diǎn)看第21行代碼及之后的代碼)。

                  
                    在這里插入代碼片
    
                  
                

    你應(yīng)該不理解第22行代碼:yield scrapy.Request(real_url, callback=self.parse_job)的意思。我跟你解釋一下。

    scrapy.Request是構(gòu)造requests對象的類。real_url是我們往requests對象里傳入的每家公司招聘信息網(wǎng)址的參數(shù)。

    callback的中文意思是回調(diào)。self.parse_job是我們新定義的parse_job方法。往requests對象里傳入callback=self.parse_job這個(gè)參數(shù)后,引擎就能知道response要前往的下一站,是parse_job()方法。

    yield語句就是用來把這個(gè)構(gòu)造好的requests對象傳遞給引擎。

    第26-42行代碼:提取出公司名稱、職位名稱、工作地點(diǎn)和招聘要求這些數(shù)據(jù),并把這些數(shù)據(jù)放進(jìn)我們定義好的JobuiItem類里。

    最后,用yield語句把item傳遞給引擎,整個(gè)核心代碼就編寫完啦!ヽ(???)?(???)?
    存儲文件

    至此,我們整個(gè)項(xiàng)目還差存儲數(shù)據(jù)這一步。在第6關(guān),我們學(xué)過用csv模塊把數(shù)據(jù)存儲csv文件,用openpyxl模塊把數(shù)據(jù)存儲Excel文件。

    其實(shí),在Scrapy里,把數(shù)據(jù)存儲成csv文件和Excel文件,也有分別對應(yīng)的方法。我們先說csv文件。

    存儲成csv文件的方法比較簡單,只需在settings.py文件里,添加如下的代碼即可。

                  
                    FEED_URI='./storage/data/%(name)s.csv'
    FEED_FORMAT='CSV'
    FEED_EXPORT_ENCODING='ansi'
    
                  
                

    FEED_URI是導(dǎo)出文件的路徑。’./storage/data/%(name)s.csv’,就是把存儲的文件放到與settings.py文件同級的storage文件夾的data子文件夾里。

    FEED_FORMAT 是導(dǎo)出數(shù)據(jù)格式,寫CSV就能得到CSV格式。

    FEED_EXPORT_ENCODING 是導(dǎo)出文件編碼,ansi是一種在windows上的編碼格式,你也可以把它變成utf-8用在mac電腦上。

    存儲成Excel文件的方法要稍微復(fù)雜一些,我們需要先在setting.py里設(shè)置啟用ITEM_PIPELINES,設(shè)置方法如下:

                  
                    #需要修改`ITEM_PIPELINES`的設(shè)置代碼:
    
    # Configure item pipelines
    # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    #ITEM_PIPELINES = {
    #     'jobuitest.pipelines.JobuitestPipeline': 300,
    # }
    
    
                  
                

    只要取消ITEM_PIPELINES的注釋(刪掉#)即可。

                  
                    #取消`ITEM_PIPELINES`的注釋后:
    
    # Configure item pipelines
    # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    ITEM_PIPELINES = {
         'jobuitest.pipelines.JobuitestPipeline': 300,
    }
    
    
                  
                

    接著,我們就可以去編輯pipelines.py文件。存儲為Excel文件,我們依舊是用openpyxl模塊來實(shí)現(xiàn),代碼如下,注意閱讀注釋:

                  
                    import openpyxl
    
    class JobuiPipeline(object):
    #定義一個(gè)JobuiPipeline類,負(fù)責(zé)處理item
        def __init__(self):
        #初始化函數(shù) 當(dāng)類實(shí)例化時(shí)這個(gè)方法會自啟動(dòng)
            self.wb =openpyxl.Workbook()
            #創(chuàng)建工作薄
            self.ws = self.wb.active
            #定位活動(dòng)表
            self.ws.append(['公司', '職位', '地址', '招聘信息'])
            #用append函數(shù)往表格添加表頭
            
        def process_item(self, item, spider):
        #process_item是默認(rèn)的處理item的方法,就像parse是默認(rèn)處理response的方法
            line = [item['company'], item['position'], item['address'], item['detail']]
            #把公司名稱、職位名稱、工作地點(diǎn)和招聘要求都寫成列表的形式,賦值給line
            self.ws.append(line)
            #用append函數(shù)把公司名稱、職位名稱、工作地點(diǎn)和招聘要求的數(shù)據(jù)都添加進(jìn)表格
            return item
            #將item丟回給引擎,如果后面還有這個(gè)item需要經(jīng)過的itempipeline,引擎會自己調(diào)度
    
        def close_spider(self, spider):
        #close_spider是當(dāng)爬蟲結(jié)束運(yùn)行時(shí),這個(gè)方法就會執(zhí)行
            self.wb.save('./jobui.xlsx')
            #保存文件
            self.wb.close()
            #關(guān)閉文件
    
    
    
                  
                

    修改設(shè)置

    在最后,我們還要再修改Scrapy中settings.py文件里的默認(rèn)設(shè)置:添加請求頭,以及把 ROBOTSTXT_OBEY=True 改成 ROBOTSTXT_OBEY=False

                  
                    #需要修改的默認(rèn)設(shè)置:
    
    # Crawl responsibly by identifying yourself (and your website) on the user-agent
    #USER_AGENT = 'douban (+http://www.yourdomain.com)'
    
    # Obey robots.txt rules
    ROBOTSTXT_OBEY = True
    
    
                  
                

    還有一處默認(rèn)設(shè)置我們需要修改,代碼如下:

                  
                    # Configure a delay for requests for the same website (default: 0)
    # See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
    # See also autothrottle settings and docs
    #DOWNLOAD_DELAY = 0
    
    
                  
                

    我們需要取消DOWNLOAD_DELAY = 0這行的注釋(刪掉#)。DOWNLOAD_DELAY翻譯成中文是下載延遲的意思,這行代碼可以控制爬蟲的速度。因?yàn)檫@個(gè)項(xiàng)目的爬取速度不宜過快,我們要把下載延遲的時(shí)間改成0.5秒。

    改好后的代碼如下:

                  
                    # Configure a delay for requests for the same website (default: 0)
    # See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
    # See also autothrottle settings and docs
    DOWNLOAD_DELAY = 0.5
    
    
                  
                

    修改完設(shè)置,我們已經(jīng)可以運(yùn)行代碼。


    更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

    微信掃碼或搜索:z360901061

    微信掃一掃加我為好友

    QQ號聯(lián)系: 360901061

    您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

    【本文對您有幫助就好】

    您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

    發(fā)表我的評論
    最新評論 總共0條評論
    主站蜘蛛池模板: 国产99对白在线播放 | 欧美在线观看视频网站 | 噜噜狠狠 | 97在线观看中心 | 国产精品久久久久影视不卡 | 九月丁香婷婷亚洲综合色 | 久久久久久久免费 | 爱操在线视频 | 中国一级特黄大片毛片 | xxxxxx国产精品视频 | 亚洲精品一级一区二区三区 | 成人97在线观看免费高清 | 国产一区二区精品久 | 中文字幕在线看视频一区二区三区 | 国产精品一国产精品免费 | 日韩视频网址 | 最新亚洲精品国自产在线观看 | 一区二区三区国产精品 | 四虎网址大全 | 欧美成人丝袜视频在线观看 | 天天做天天爱夜夜想毛片 | 夜夜操女人 | 日韩精品久久久久久 | 狠狠色噜噜狠狠狠狠五月婷 | 国产精品亚洲一区二区三区正片 | 青草久草| 最好看的毛片 | 久久r精品 | 天天综合日日噜噜噜 | 日本不卡影院 | 日本一级毛片一级裸片 | 久久亚洲精品中文字幕三区 | 国产日本久久久久久久久婷婷 | 日韩久久精品视频 | 中文字幕在线视频免费观看 | 黄色小视频免费看 | 久草在线看片 | 99网站 | 日本一级毛片视频无遮挡免费 | 337p亚洲精品色噜噜狠狠 | 精品久久久久久乐 |