<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      一、寫(xiě)在前面


        我寫(xiě)爬蟲(chóng)已經(jīng)寫(xiě)了一段時(shí)間了,對(duì)于那些使用GET請(qǐng)求或者POST請(qǐng)求的網(wǎng)頁(yè),爬取的時(shí)候都還算得心應(yīng)手。不過(guò)最近遇到了一個(gè)有趣的網(wǎng)站,雖然爬取的難度不大,不過(guò)因?yàn)楸韱翁峤坏拇嬖?,所以一開(kāi)始還是有點(diǎn)摸不著頭腦。至于最后怎么解決的,請(qǐng)慢慢往下看。

      ?

      二、頁(yè)面分析

        這次爬取的網(wǎng)站是:https://www.ctic.org/crm?tdsourcetag=s_pctim_aiomsg
      <https://www.ctic.org/crm?tdsourcetag=s_pctim_aiomsg>
      ,該網(wǎng)站提供了美國(guó)的一些農(nóng)田管理的數(shù)據(jù)。要查看具體的數(shù)據(jù),需要選擇年份、單位、地區(qū)、作物種類等,如下圖:



        根據(jù)以往的經(jīng)驗(yàn),這種表單提交都是通過(guò)ajax來(lái)完成的,所以熟練地按F12打開(kāi)開(kāi)發(fā)者工具,選擇XHR選項(xiàng),然后點(diǎn)擊“View
      Summary”,結(jié)果卻什么都沒(méi)有......



        這是怎么回事?不急,切換到All看一下有沒(méi)有什么可疑的東西。果然就找到了下面這個(gè),可以看到在Form
      Data中包含了很多參數(shù),而且可以很明顯看出來(lái)是一些年份、地區(qū)等信息,這就是表單提交的內(nèi)容:




        可以注意到在這些參數(shù)中有一個(gè)_csrf,很明顯是一個(gè)加密參數(shù),那么要怎么得到這個(gè)參數(shù)呢?返回填寫(xiě)表單的網(wǎng)頁(yè),在開(kāi)發(fā)者工具中切換到Elements,然后搜索_csrf看看,很快就找到了如下信息:




        其余參數(shù)都是表單中所選擇的內(nèi)容,只要對(duì)應(yīng)填寫(xiě)就行了。不過(guò)這個(gè)請(qǐng)求返回的狀態(tài)碼是302,為什么會(huì)是302呢?302狀態(tài)碼的使用場(chǎng)景是請(qǐng)求的資源暫時(shí)駐留在不同的URI下,因此還需要繼續(xù)尋找。



        通過(guò)進(jìn)一步查找可知,最終的URL是:https://www.ctic.org/crm/?action=result。

        

      三、主要步驟?

      1.爬取郡縣信息


        可以看到表單中包含了地區(qū)、州、郡縣選項(xiàng),在填寫(xiě)表單的時(shí)候,這一部分都是通過(guò)JS來(lái)實(shí)現(xiàn)的。打開(kāi)開(kāi)發(fā)者工具,然后在頁(yè)面上點(diǎn)選County,選擇Region和State,就能在開(kāi)發(fā)者工具中找到相應(yīng)的請(qǐng)求。主要有兩個(gè)請(qǐng)求,如下:

      https://www.ctic.org/admin/custom/crm/getstates/

      https://www.ctic.org/admin/custom/crm/getcounties/

        這兩個(gè)請(qǐng)求返回的結(jié)果格式如下圖:



        這里可以使用正則匹配,也可以使用lxml來(lái)解析,我選擇使用后者。示例代碼如下:
      1 from lxml import etree 2 3 4 html = '"<option
      value=\"Autauga\">Autauga<\/option><option
      value=\"Baldwin\">Baldwin<\/option><option
      value=\"Barbour\">Barbour<\/option><option value=\"Bibb\">Bibb<\/option><option
      value=\"Blount\">Blount<\/option><option
      value=\"Bullock\">Bullock<\/option><option
      value=\"Butler\">Butler<\/option><option
      value=\"Calhoun\">Calhoun<\/option><option
      value=\"Chambers\">Chambers<\/option><option
      value=\"Cherokee\">Cherokee<\/option><option
      value=\"Chilton\">Chilton<\/option><option
      value=\"Choctaw\">Choctaw<\/option><option
      value=\"Clarke\">Clarke<\/option><option value=\"Clay\">Clay<\/option><option
      value=\"Cleburne\">Cleburne<\/option><option
      value=\"Coffee\">Coffee<\/option><option
      value=\"Colbert\">Colbert<\/option><option
      value=\"Conecuh\">Conecuh<\/option><option
      value=\"Coosa\">Coosa<\/option><option
      value=\"Covington\">Covington<\/option><option
      value=\"Crenshaw\">Crenshaw<\/option><option
      value=\"Cullman\">Cullman<\/option><option value=\"Dale\">Dale<\/option><option
      value=\"Dallas\">Dallas<\/option><option
      value=\"Dekalb\">Dekalb<\/option><option
      value=\"Elmore\">Elmore<\/option><option
      value=\"Escambia\">Escambia<\/option><option
      value=\"Etowah\">Etowah<\/option><option
      value=\"Fayette\">Fayette<\/option><option
      value=\"Franklin\">Franklin<\/option><option
      value=\"Geneva\">Geneva<\/option><option
      value=\"Greene\">Greene<\/option><option value=\"Hale\">Hale<\/option><option
      value=\"Henry\">Henry<\/option><option
      value=\"Houston\">Houston<\/option><option
      value=\"Jackson\">Jackson<\/option><option
      value=\"Jefferson\">Jefferson<\/option><option
      value=\"Lamar\">Lamar<\/option><option
      value=\"Lauderdale\">Lauderdale<\/option><option
      value=\"Lawrence\">Lawrence<\/option><option value=\"Lee\">Lee<\/option><option
      value=\"Limestone\">Limestone<\/option><option
      value=\"Lowndes\">Lowndes<\/option><option
      value=\"Macon\">Macon<\/option><option
      value=\"Madison\">Madison<\/option><option
      value=\"Marengo\">Marengo<\/option><option
      value=\"Marion\">Marion<\/option><option
      value=\"Marshall\">Marshall<\/option><option
      value=\"Mobile\">Mobile<\/option><option
      value=\"Monroe\">Monroe<\/option><option
      value=\"Montgomery\">Montgomery<\/option><option
      value=\"Morgan\">Morgan<\/option><option value=\"Perry\">Perry<\/option><option
      value=\"Pickens\">Pickens<\/option><option value=\"Pike\">Pike<\/option><option
      value=\"Randolph\">Randolph<\/option><option
      value=\"Russell\">Russell<\/option><option
      value=\"Shelby\">Shelby<\/option><option value=\"St Clair\">St
      Clair<\/option><option value=\"Sumter\">Sumter<\/option><option
      value=\"Talladega\">Talladega<\/option><option
      value=\"Tallapoosa\">Tallapoosa<\/option><option
      value=\"Tuscaloosa\">Tuscaloosa<\/option><option
      value=\"Walker\">Walker<\/option><option
      value=\"Washington\">Washington<\/option><option
      value=\"Wilcox\">Wilcox<\/option><option value=\"Winston\">Winston<\/option>"' 5
      et = etree.HTML(html) 6 result = et.xpath('//option/text()') 7 result =
      [i.rstrip('"') for i in result] 8 print(result)
        上面代碼輸出的結(jié)果為:

      ['Autauga', 'Baldwin', 'Barbour', 'Bibb', 'Blount', 'Bullock', 'Butler',
      'Calhoun', 'Chambers', 'Cherokee', 'Chilton', 'Choctaw', 'Clarke', 'Clay',
      'Cleburne', 'Coffee', 'Colbert', 'Conecuh', 'Coosa', 'Covington', 'Crenshaw',
      'Cullman', 'Dale', 'Dallas', 'Dekalb', 'Elmore', 'Escambia', 'Etowah',
      'Fayette', 'Franklin', 'Geneva', 'Greene', 'Hale', 'Henry', 'Houston',
      'Jackson', 'Jefferson', 'Lamar', 'Lauderdale', 'Lawrence', 'Lee', 'Limestone',
      'Lowndes', 'Macon', 'Madison', 'Marengo', 'Marion', 'Marshall', 'Mobile',
      'Monroe', 'Montgomery', 'Morgan', 'Perry', 'Pickens', 'Pike', 'Randolph',
      'Russell', 'Shelby', 'St Clair', 'Sumter', 'Talladega', 'Tallapoosa',
      'Tuscaloosa', 'Walker', 'Washington', 'Wilcox', 'Winston']

        獲取所有郡縣信息的思路為分別選擇四個(gè)地區(qū),然后遍歷每個(gè)地區(qū)下面的州,再遍歷每個(gè)州所包含的郡縣,最終得到所有郡縣信息。

      2.爬取農(nóng)田數(shù)據(jù)


      ?  在得到郡縣信息之后,就可以構(gòu)造獲取農(nóng)田數(shù)據(jù)的請(qǐng)求所需要的參數(shù)了。在獲取農(nóng)田數(shù)據(jù)之前,需要向服務(wù)器發(fā)送一個(gè)提交表單的請(qǐng)求,不然是得不到數(shù)據(jù)的。在我測(cè)試的時(shí)候,發(fā)送提交表單的請(qǐng)求的時(shí)候,返回的狀態(tài)碼并不是302,不過(guò)這并不影響之后的操作,所以可以忽略掉。


        需要注意的是,參數(shù)中是有一個(gè)年份信息的,前面我一直是默認(rèn)用的2011,不過(guò)要爬取更多信息的話,還需要改變這個(gè)年份信息。而通過(guò)選擇頁(yè)面元素可以知道,這個(gè)網(wǎng)站提供了16個(gè)年份的農(nóng)田數(shù)據(jù)信息,這16個(gè)年份為:

      [1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,2002,2004,2006,2007,2008,2011]

        得到這些年份信息之后,就可以和前面的郡縣信息進(jìn)行排列組合得到所有提交表單的請(qǐng)求所需要的參數(shù)。說(shuō)道排列組合,一般會(huì)用for循環(huán)來(lái)實(shí)現(xiàn),不過(guò)這里推薦一種方法,就是使用itertools.product,使用示例如下:
      1 from itertools import product 2 3 a = [1, 2, 3] 4 b = [2, 4] 5 result =
      product(a, b) 6 for i in result: 7 print(i, end=" ") 8 9 10 # (1, 2) (1, 4)
      (2, 2) (2, 4) (3, 2) (3, 4)

        下面是農(nóng)田數(shù)據(jù)的部分截圖,其中包含了很多種類的作物,還有對(duì)應(yīng)的耕地面積信息,不過(guò)在這個(gè)表中有些我們不需要的信息,比如耕地面積總量信息,還有空白行,這都是干擾數(shù)據(jù),在解析的時(shí)候要清洗掉。



        解析農(nóng)田數(shù)據(jù)部分的代碼如下:
      1 et = etree.HTML(html) 2 crop_list = et.xpath('
      //*[@id="crm_results_eight"]/tbody/tr/td[1]/text()') # 作物名稱 3 area_list =
      et.xpath('//*[@id="crm_results_eight"]/tbody/tr/td[2]/text()') # 耕地面積 4
      conservation_list = et.xpath('//*[@id="crm_results_eight"]/tbody/tr/td[6]/text()
      ') # 受保護(hù)耕地面積 5 crop_list = crop_list[:-3] 6 area_list = area_list[:-3] 7
      conservation_list = conservation_list[:-3]
      ?

      ?完整代碼已上傳到GitHub <https://github.com/TM0831/Spiders/tree/master/CRMSpider>!

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問(wèn)題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          有码一区二区三区四区 | 亚洲性爱小说图片 | 成人午夜免费无码区无码A片在线观看 | 艳妇臀荡乳欲伦岳txt下载 | 两老头把我添高潮了 | 甘雨大战史莱姆视频动画免费观看 | 看免费操逼片 | 大鸡巴操我视频 | 免费国产污网站 | 免费观看亚洲视频 |