日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二、scrapy爬虫框架——scrapy构造并发送请求

發(fā)布時(shí)間:2024/7/5 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二、scrapy爬虫框架——scrapy构造并发送请求 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

scrapy數(shù)據(jù)建模與請求

學(xué)習(xí)目標(biāo):
  • 應(yīng)用 在scrapy項(xiàng)目中進(jìn)行建模
  • 應(yīng)用 構(gòu)造Request對象,并發(fā)送請求
  • 應(yīng)用 利用meta參數(shù)在不同的解析函數(shù)中傳遞數(shù)據(jù)

  • 1. 數(shù)據(jù)建模

    通常在做項(xiàng)目的過程中,在items.py中進(jìn)行數(shù)據(jù)建模

    1.1 為什么建模

  • 定義item即提前規(guī)劃好哪些字段需要抓,防止手誤,因?yàn)槎x好之后,在運(yùn)行過程中,系統(tǒng)會(huì)自動(dòng)檢查
  • 配合注釋一起可以清晰的知道要抓取哪些字段,沒有定義的字段不能抓取,在目標(biāo)字段少的時(shí)候可以使用字典代替
  • 使用scrapy的一些特定組件需要Item做支持,如scrapy的ImagesPipeline管道類,百度搜索了解更多
  • 1.2 如何建模

    在items.py文件中定義要提取的字段:

    class MyspiderItem(scrapy.Item): name = scrapy.Field() # 講師的名字title = scrapy.Field() # 講師的職稱desc = scrapy.Field() # 講師的介紹

    1.3 如何使用模板類

    模板類定義以后需要在爬蟲中導(dǎo)入并且實(shí)例化,之后的使用方法和使用字典相同

    job.py:

    from myspider.items import MyspiderItem # 導(dǎo)入Item,注意路徑 ...def parse(self, response)item = MyspiderItem() # 實(shí)例化后可直接使用item['name'] = node.xpath('./h3/text()').extract_first()item['title'] = node.xpath('./h4/text()').extract_first()item['desc'] = node.xpath('./p/text()').extract_first()print(item)

    注意:

  • from myspider.items import MyspiderItem這一行代碼中 注意item的正確導(dǎo)入路徑,忽略pycharm標(biāo)記的錯(cuò)誤
  • python中的導(dǎo)入路徑要訣:從哪里開始運(yùn)行,就從哪里開始導(dǎo)入
  • 1.4 開發(fā)流程總結(jié)

  • 創(chuàng)建項(xiàng)目

    scrapy startproject 項(xiàng)目名
  • 明確目標(biāo)

    在items.py文件中進(jìn)行建模
  • 創(chuàng)建爬蟲

    3.1 創(chuàng)建爬蟲

    scrapy genspider 爬蟲名 允許的域
    3.2 完成爬蟲

    修改start_urls
    檢查修改allowed_domains
    編寫解析方法
  • 保存數(shù)據(jù)

    在pipelines.py文件中定義對數(shù)據(jù)處理的管道

    在settings.py文件中注冊啟用管道
  • 2. 翻頁請求的思路

    對于要提取如下圖中所有頁面上的數(shù)據(jù)該怎么辦?

    回顧requests模塊是如何實(shí)現(xiàn)翻頁請求的:

  • 找到下一頁的URL地址
  • 調(diào)用requests.get(url)
  • scrapy實(shí)現(xiàn)翻頁的思路:

  • 找到下一頁的url地址
  • 構(gòu)造url地址的請求對象,傳遞給引擎
  • 3. 構(gòu)造Request對象,并發(fā)送請求

    3.1 實(shí)現(xiàn)方法

  • 確定url地址
  • 構(gòu)造請求,scrapy.Request(url,callback)
    • callback:指定解析函數(shù)名稱,表示該請求返回的響應(yīng)使用哪一個(gè)函數(shù)進(jìn)行解析
  • 把請求交給引擎:yield scrapy.Request(url,callback)
  • 3.2 網(wǎng)易招聘爬蟲

    通過爬取網(wǎng)易招聘的頁面的招聘信息,學(xué)習(xí)如何實(shí)現(xiàn)翻頁請求

    地址:https://hr.163.com/position/list.do

    思路分析:
  • 獲取首頁的數(shù)據(jù)
  • 尋找下一頁的地址,進(jìn)行翻頁,獲取數(shù)據(jù)
  • 注意:
  • 可以在settings中設(shè)置ROBOTS協(xié)議
  • # False表示忽略網(wǎng)站的robots.txt協(xié)議,默認(rèn)為True ROBOTSTXT_OBEY = False
  • 可以在settings中設(shè)置User-Agent:
  • # scrapy發(fā)送的每一個(gè)請求的默認(rèn)UA都是設(shè)置的這個(gè)User-Agent USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'

    3.3 代碼實(shí)現(xiàn)

    在爬蟲文件的parse方法中:

    ......# 提取下一頁的hrefnext_url = response.xpath('//a[contains(text(),">")]/@href').extract_first()# 判斷是否是最后一頁if next_url != 'javascript:void(0)':# 構(gòu)造完整urlurl = 'https://hr.163.com/position/list.do' + next_url# 構(gòu)造scrapy.Request對象,并yield給引擎# 利用callback參數(shù)指定該Request對象之后獲取的響應(yīng)用哪個(gè)函數(shù)進(jìn)行解析yield scrapy.Request(url, callback=self.parse) ......

    3.4 scrapy.Request的更多參數(shù)

    scrapy.Request(url[,callback,method="GET",headers,body,cookies,meta,dont_filter=False])
    參數(shù)解釋
  • 中括號里的參數(shù)為可選參數(shù)
  • callback:表示當(dāng)前的url的響應(yīng)交給哪個(gè)函數(shù)去處理
  • meta:實(shí)現(xiàn)數(shù)據(jù)在不同的解析函數(shù)中傳遞,meta默認(rèn)帶有部分?jǐn)?shù)據(jù),比如下載延遲,請求深度等
  • dont_filter:默認(rèn)為False,會(huì)過濾請求的url地址,即請求過的url地址不會(huì)繼續(xù)被請求,對需要重復(fù)請求的url地址可以把它設(shè)置為Ture,比如貼吧的翻頁請求,頁面的數(shù)據(jù)總是在變化;start_urls中的地址會(huì)被反復(fù)請求,否則程序不會(huì)啟動(dòng)
  • method:指定POST或GET請求
  • headers:接收一個(gè)字典,其中不包括cookies
  • cookies:接收一個(gè)字典,專門放置cookies
  • body:接收json字符串,為POST的數(shù)據(jù),發(fā)送payload_post請求時(shí)使用(在下一章節(jié)中會(huì)介紹post請求)
  • 4. meta參數(shù)的使用

    meta的作用:meta可以實(shí)現(xiàn)數(shù)據(jù)在不同的解析函數(shù)中的傳遞

    在爬蟲文件的parse方法中,提取詳情頁增加之前callback指定的parse_detail函數(shù):

    def parse(self,response):...yield scrapy.Request(detail_url, callback=self.parse_detail,meta={"item":item}) ...def parse_detail(self,response):#獲取之前傳入的itemitem = resposne.meta["item"]
    特別注意
  • meta參數(shù)是一個(gè)字典
  • meta字典中有一個(gè)固定的鍵proxy,表示代理ip,關(guān)于代理ip的使用我們將在scrapy的下載中間件的學(xué)習(xí)中進(jìn)行介紹

  • 小結(jié)

  • 完善并使用Item數(shù)據(jù)類:
  • 在items.py中完善要爬取的字段
  • 在爬蟲文件中先導(dǎo)入Item
  • 實(shí)力化Item對象后,像字典一樣直接使用
  • 構(gòu)造Request對象,并發(fā)送請求:
  • 導(dǎo)入scrapy.Request類
  • 在解析函數(shù)中提取url
  • yield scrapy.Request(url, callback=self.parse_detail, meta={})
  • 利用meta參數(shù)在不同的解析函數(shù)中傳遞數(shù)據(jù):
  • 通過前一個(gè)解析函數(shù) yield scrapy.Request(url, callback=self.xxx, meta={}) 來傳遞meta
  • 在self.xxx函數(shù)中 response.meta.get(‘key’, ‘’) 或 response.meta[‘key’] 的方式取出傳遞的數(shù)據(jù)

  • 參考代碼

    wangyi/spiders/job.py

    import scrapy from wangyi.items import WangyiItemclass JobSpider(scrapy.Spider):name = 'job'# 2、檢查修改域名allowed_domains = ['163.com']# 1、修改起始urlstart_urls = ['https://hr.163.com/position/list.do']# 3、解析數(shù)據(jù)def parse(self, response):# 提取數(shù)據(jù)# 獲取所有職位節(jié)點(diǎn)列表node_list = response.xpath('//*[@class="position-tb"]/tbody/tr')# print(len(node_list))# 遍歷節(jié)點(diǎn)列表,通過枚舉來過濾掉沒用的節(jié)點(diǎn)for num,node in enumerate(node_list):# print(num,node)# 設(shè)置過濾條件,將目標(biāo)節(jié)點(diǎn)獲取出來if num % 2 ==0:item = WangyiItem()item['name'] = node.xpath('./td[1]/a/text()').extract_first()# item['link'] = "https://hr.163.com/" + node.xpath('./td[1]/a/@href').extract_first()# response.urljoin()用來拼接相對路徑的url,可以理解成自動(dòng)補(bǔ)全item['link'] = response.urljoin(node.xpath('./td[1]/a/@href').extract_first())item['depart'] = node.xpath('./td[2]/text()').extract_first()item['category'] = node.xpath('./td[3]/text()').extract_first()item['type'] = node.xpath('./td[4]/text()').extract_first()item['address'] = node.xpath('./td[5]/text()').extract_first()# strip()方法去掉字符串前后的空格item['num'] = node.xpath('./td[6]/text()').extract_first().strip()item['date'] = node.xpath('./td[7]/text()').extract_first()# print(item)# yield item# 構(gòu)建詳情頁面的請求yield scrapy.Request(url = item['link'],callback = self.parse_detail,meta = {'item':item})# 模擬翻頁part_url = response.xpath('/html/body/div[2]/div[2]/div[2]/div/a[last()]/@href').extract_first()# 判斷終止條件if part_url != 'javascript:void(0)':next_url = response.urljoin(part_url)# 構(gòu)建請求對象,并且返回給引擎yield scrapy.Request(url = next_url,callback = self.parse)# 定義詳情頁面的數(shù)據(jù)解析方法def parse_detail(self,response):# 將meta傳參獲取# print('------------------',response.meta['item'])item = response.meta['item']# 提取剩余字段數(shù)據(jù)item['duty'] = ''.join(response.xpath('/html/body/div[2]/div[2]/div[1]/div/div/div[2]/div[1]/div/text()').extract()).strip()item['require'] = ''.join(response.xpath('/html/body/div[2]/div[2]/div[1]/div/div/div[2]/div[2]/div/text()').extract()).strip()# print(item)# 返回給引擎yield item

    wangyi/items.py

    # Define here the models for your scraped items # # See documentation in: # https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass WangyiItem(scrapy.Item):# define the fields for your item here like:name = scrapy.Field() # 職位名稱link = scrapy.Field() # 點(diǎn)擊鏈接depart = scrapy.Field() # 所屬部門category = scrapy.Field() # 職位類型type = scrapy.Field() # 工作類型address = scrapy.Field() # 工作地點(diǎn)num = scrapy.Field() # 招聘人數(shù)date = scrapy.Field() # 發(fā)布時(shí)間duty = scrapy.Field() # 崗位描述require = scrapy.Field() # 崗位要求

    總結(jié)

    以上是生活随笔為你收集整理的二、scrapy爬虫框架——scrapy构造并发送请求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。