【需求】
使用scrapy抓取(’糗事百科’-‘文字’)https://www.qiushibaike.com/text/ 所有分頁所對應的作者及段子信息
補充一個知識點:假如抓取的原始文字中有\r\n\t出現,則在xpath表達式中需要使用normalize-space 函數函數:語法是:normalize-space('xpath表達式')
例子:author = content.xpath('normalize-space(./div/a[2]/h2/text())').extract_first()
【實現代碼】
1 # -*- coding: utf-8 -*- 2 import scrapy 3 from qiushibaike.items import QiushibaikeItem 4 5 6 class QiushiTextSpider(scrapy.Spider): 7 #爬蟲文件名稱:通過爬蟲文件的名稱可以指定定位到某一個具體的爬蟲文件 8 name = 'qiushi_text' 9 '''允許的域名:只可以爬取指定域名下的頁面數據,由於我們爬取的鏈接內容在爬取過程中可能跳轉至 10 不是此域名下的url,因此在沒有特殊要求的情況下,這條命令可以注釋掉''' 11 #allowed_domains = ['https://www.qiushibaike.com/text/'] 12 #起始url:當前項目將要爬取的頁面所對應的url 13 start_urls = ['https://www.qiushibaike.com/text//'] 14 15 #指定初始頁碼 16 page_num = 1 17 url = 'https://www.qiushibaike.com/text/page/%d/' 18 19 '''解析方法:對獲取的頁面數據進行指定內容的解析 20 response:根據起始url列表發起請求,請求成功后返回的響應對象 21 注: 22 1.parse方法的返回值:必須為迭代器(常見字典/列表等)或者空 23 2.建議大家使用xpath進行指定內容的解析:框架集成了xpath的接口 24 ''' 25 def parse(self, response): 26 27 url 28 #定義用戶存儲作者和段子內容的列表 29 data_list = [] 30 content_list = response.xpath('//div[@id="content-left"]/div') 31 for content in content_list: 32 '''1.xpath解析到的指定內容被存儲到了Selector對象 33 2.extract()方法可以將Selector對象中存儲的數據拿到 34 3.extract_first()等價於extract()[0]''' 35 author = content.xpath('./div/a[2]/h2/text()').extract_first() 36 content_detail = content.xpath('.//div[@class="content"]/span/text()').extract()[0] 37 #將解析到的數據值存儲到items對象 38 item = QiushibaikeItem() 39 item['author']=author 40 item['content_detail']=content_detail 41 42 #將item對象提交給管道 43 yield item 44 #爬取所有頁面數據,最大為13頁 45 if self.page_num <= 13: 46 print("爬取到了第%d頁數據"%self.page_num) 47 self.page_num+=1 48 next_url = format(self.url % self.page_num) 49 #遞歸爬取數據:callback參數的值為回調函數(將url請求后,得到的相應數據繼續進行parse解析) 50 #遞歸調用parse函數 51 yield scrapy.Request(url=next_url,callback=self.parse)
此章節重點學習遞歸爬取數據,涉及到的方法如下(其它內容請參加前幾張內容):
yield scrapy.Request(url=next_url,callback=self.parse)
如若執行過程中出現報錯信息:(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '相關文字' at line 6")是由於sql語句寫的有問題:
問題sql:不要用%或者+操作符來拼接SQL語句(容易出錯)
sql = 'insert into qiushi_text (author,content) values("%s","%s")'%(item['author'],item['content_detail'])
self.cursor.execute(sql)
正確sql:(使用占位符,即execute的第二個參數進行賦值)推薦使用這一種
sql = 'insert into qiushi_text (author,content) values("%s","%s")'
self.cursor.execute(sql,(item['author'],item['content_detail']))
如若執行過程中出現報錯信息:
(1366, "Incorrect string value: '\\xF0\\x9F\\x98\\x82\\x0A\\x0A...' for column 'content' at row 1")
是由於部分字符及emoji表情占用4個字符存儲,而mysql不能識別4個字節的utf8編碼的字符(utf8默認是一個字符3個字節),而出現的編碼錯誤。因此只需將數據庫的編碼方式設置為utf8mb4即可
注:本內容僅供參考學習,勿用作他用。