1.页面分析
- 需求:爬取糗事百科段子板块的
用户名,标题,发布时间,好笑数,内容
- 分析:爬取的数据没有在同一张页面中,
- 使用链接提取器提取所有的
页码链接
; - 使用链接提取器提取所有段子
详情页的链接
。
- 使用链接提取器提取所有的
2.用 Scrapy 编写网络爬虫
2.1 创建和使用 Scrapy 工程
Scrapy 框架提供了一个 scrapy 命令用来建立 Scrapy 工程,可以使用下面的命令建立一个名为qiubai_crawl 的 Scrapy 工程。
scrapy startproject qiubai_crawl
然后,通过命令创建出爬虫文件,爬虫文件为主要的代码作业文件,通常一个网站的爬取动作都会在爬虫文件中进行编写。命令如下:
cd myscrapy
scrapy genspider -t crawl qiubai_spider www.xxx.com
2.2 示例代码
- qiubai_spider.py
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import QiubaiCrawlItem, DetailItem
class QiubaiSpiderSpider(CrawlSpider):
name = 'qiubai_spider'
start_urls = ['https://www.qiushibaike.com/text/']
link = LinkExtractor(allow=r'page/\d/') # 页码链接提取器
link2 = LinkExtractor(allow=r'article/\d+') # 页码链接提取器
# 规则解析器
rules = (
Rule(link, callback='parse_item', follow=True),
Rule(link2, callback='parse_detail', follow=True),
)
def parse_item(self, response):
div_list = response.xpath('//div[@class="col1 old-style-col1"]/div')
for div in div_list:
username = div.xpath('.//h2/text()').extract_first()
wz_id = div.xpath('./@id').extract_first()
item = QiubaiCrawlItem()
item['username'] = username
item['wz_id'] = wz_id
yield item
def parse_detail(self, response):
title_id = response.xpath('//*[@id="qiushi_tag_123400977"]/@id').extract_first()
title = response.xpath('//*[@id="content"]/div/div[2]/h1/text()').extract_first()
time = response.xpath('//*[@id="content"]/div/div[2]/div[1]/span[1]/text()').extract_first()
comment = response.xpath('//*[@id="single-next-link"]/div//text()').extract()
comment = "".join(comment)
item = DetailItem()
item['title_id'] = title_id
item['title'] = title
item['time'] = time
item['comment'] = comment
yield item
LinkExtractor() 链接提取器:根据指定的规则(allow)进行指定链接的提取
Rule() 规则解析器:
将链接提取器提取到的链接进行指定规则(callback)的解析
- items.py
import scrapy
class QiubaiCrawlItem(scrapy.Item):
username = scrapy.Field()
wz_id = scrapy.Field()
class DetailItem(scrapy.Item):
title_id = scrapy.Field()
title = scrapy.Field()
time = scrapy.Field()
comment = scrapy.Field()
- pipelines.py
class QiubaiCrawlPipeline:
def process_item(self, item, spider):
# 如何判断item类型
# 将数据写入数据库时,如何保证数据的一致性?tem['wz_id']=item['title_id']
if item.__class__.__name__ == 'QiubaiCrawlItem':
print(item['username'], item['wz_id'])
else:
print(item['title_id'], item['title'], item['time'], item['comment'])
return item
- setting.py: 开启管道