学习了Scrapy来爬取数据,来实践来爬取当当图书的畅销榜的图书。
1.创建工程
# 创建工程scrapy startporject dangdang# 创建爬虫cd dangdang 进入dangdang这个工程里面# 创建dangdang_book的爬虫, 开始的网址为scrapy genspider dangdang_book ""
2.配置items.py settings.py
# 设置 itemclass DangdangItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()# 这些是这个定义的内容 book_name, author , pricebook_name = scrapy.Field() author = scrapy.Field()price = scrapy.Field()# 设置setting#1.日志的的等级设置LOG_LEVEL = "WARNING" # 设置成这样就不会有日志信息出来了#2.服从机器人的规则ROBOTSTXT_OBEY = False # 设置成False手动检查#3.打开item_pipeline # Configure item pipelines# See /en/latest/topics/item-pipeline.htmlITEM_PIPELINES = {'dangdang.pipelines.DangdangPipeline': 300,}# 设置爬取信息的保存路径与格式# 保存为CSVFEED_URI = './storeage/data/%(name)s.csv' # 设置路径FEED_FORMAT = 'CSV' # 设置格式FEED_EXPORT_ENCODING = 'utf-8' # 编码格式
3.设置settings.py中的USER_AGENT
用网页检查工具打开当当网的网页结构,在network里面找到header 结构最后的USER_AGENT
4.完善dangdang工程中的dangdang_book爬虫
导入bs4的BeautifulSoup模块来实现自动换行
设置所有的请求请求URL并追加到START_URL中
分析网页结构找到需要爬取的信息的主体结构,并用BeautifulSoup生成bs_data
设置item列表,其中包含'book_name','author','price'
使用find找到需要爬取信息的所在类标签及名称
爬取完毕穿给yield item
# -*- coding: utf-8 -*-import scrapyfrom bs4 import BeautifulSoupclass DangdangBookSpider(scrapy.Spider):name = 'dangdang_book'allowed_domains = ['']start_urls = ['/books/bestsellers/01.00.00.00.00.00-year--0-1-1']# /books/bestsellers/01.00.00.00.00.00-year--0-1-1# /books/bestsellers/01.00.00.00.00.00-year--0-1-2# /books/bestsellers/01.00.00.00.00.00-year--0-1-3# 构造出25个请求urlfor i in range(2, 26): #畅销书的 1,2,3... 25 页url = '/books/bestsellers/01.00.00.00.00.00-year--0-1-' + str(i)start_urls.append(url)def parse(self, response):bs_data = BeautifulSoup(response.text, 'html.parser')datas = bs_data.find('ul', class_="bang_list clearfix bang_list_mode").find_all('li') #寻找图书信息,定位到ul标签的bang_list clearfix bang_list_model类,并且寻找所有的li标签for data in datas:item = {} # 设置item列表,存储爬取的信息item['book_name'] = data.find('div', class_="name").find('a')['title'] # 在 div标签里面找到name的类,并且寻找当前的a标签,找到titleitem['author'] = data.find('div', class_="publisher_info").find('a')['title'] # 在div标签中找到publisher_info类 并且定位到title类item['price'] = data.find('div', class_="price").find('span', class_="price_n").text # 在div标签中找到price类,并且往下找到span标签中的price_n类#print("书名:{}, 作者:{}, 价格:{}".format(item['book_name'], item['author'], item['price']))yield item # 把item列表给pipeline# 这下面是之前写的历史版本# book_name = data.find('div', class_="name").find('a')['title']# print(book_name)# author = data.find('div', class_="publisher_info").text# print(author)# price = data.find('div', class_="price").find('span', class_="price_n").text# print("书名:{},作者:{},价格:{}".format(book_name, author, price))#with open("book.txt", 'a+') as file:# file.write(book_name)
5.pipelines的完善
导入openpyxl 用于创建excel文件
初始化函数_init_() 用于创建工作空间,并且往excel文件中添加表头'book_name','author','price'
处理item函数 process_item()用来处理接受的数据
关闭函数close_spider()用来保存生成的excel文件,并关闭工作空间
# -*- coding: utf-8 -*-# Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: /en/latest/topics/item-pipeline.htmlimport openpyxlclass DangdangPipeline(object):def __init__(self):# 初始化函数,当类实例化时候这个方法自动启动self.wb = openpyxl.Workbook()# 创建工作薄self.ws = self.wb.active# 定位活动表self.ws.append(['book_name', 'author', 'price']) # append 函数往表格添加表头def process_item(self, item, spider):# process_item 是默认的处理item的函数,不能被修改名字# 把我们的 'book_name', 'author', 'price' 写成一个列表,赋值给lineline = [item['book_name'], item['author'], item['price']]self.ws.append(line) # 用append函数把'book_name', 'author', 'price'添加进表格print(item)return item # 将 item返回给引擎,如果后面还有需要使用item的就会自动调度def close_spider(self, spider):self.wb.save('./dangdang_book.xls') # 保存文件self.wb.close() # 关闭文件