【需求】
使用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即可
注:本内容仅供参考学习,勿用作他用。