当前位置:   article > 正文

Python爬虫——scrapy安装和使用_python scrapy安装

python scrapy安装

目录

1.scrapy是什么?

2.安装scrapy

3.scrapy项目的创建以及运行

4.response的属性和方法

5.scrapy工作原理

6. scrapy shell

 7. yield实例

7.1 管道封装(当当网)

7.2 多条管道下载

 7.3 多网页下载

 7.4 一个item包含多级页面的数据(电影天堂)

 8 CrawlSpider(读书网)

9 数据入库 (读书网) 

10 日志信息和日志等级

11 scrapy的post请求 (百度翻译)


1.scrapy是什么?

        Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理 或存储历史数据等一系列的程序中。

2.安装scrapy

        CMD进入python编辑器所在的Scripts目录下。

pip install scrapy -i https://pypi.douban.com/simple

安装过程中可能出现的错误:

报错1:building 'twisted.test.raiser' extension

error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++

Build Tools": http://landinghub.visualstudio.com/visualcppbuildtools

解决办法:

        下载twisted库,网址:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

        注意:cp后面是 python版本,amd64代表64

         下载对应版本,下载完成后使用 pip install twisted的路径 进行安装

安装完成后在进行安装scrapy。

报错2:提示升级pip指令:python.exe m pip install ‐‐upgrade pip

解决办法:运行指令python.exe m pip install ‐‐upgrade pip 即可。

报错3: win32错误。

scrapy startproject scrapy_baidu

解决办法: 运行指令 pip install pypiwin32

3.scrapy项目的创建以及运行

        scrapy项目不能使用之前的方式创建,只能通多命令窗口的方式进行创建。

        首先我们使用命令窗口进入项目需要放到的路径下面。

3.1 输入命令创建项目。切记 scrapy的项目名不能以数字开头,不能存在汉字。

scrapy startproject scrapy_baidu

         此时我们查看pycharm编辑器,会看到出现如下内容。

 3.2 创建爬虫文件。

        要在spiders文件夹中去创建爬虫文件

                        进去创建文件的目录           cd 项目的名字\项目的名字\spiders

                        创建爬虫的文件                  scrapy genspider 爬虫文件的名字  要爬取的网页

  1. cd scrapy_baidu\scrapy_baidu\spiders
  2. scrapy genspider baidu http://www.baidu.com

         创建文件成功后,查看pycharm中spiders目录下新生成一个文件,并且修改文件如下图所示。

3.3 修改文件settings.py

3.4 运行爬虫文件        

        scrapy crawl 爬虫的名字

scrapy crawl baidu

4.response的属性和方法

        response.text                       获取的是响应的字符串

        response.body                     获取的是二进制数据

        response.xpath()                  可以直接使用xpath方法来解析response中的内容

        response.extract()                提取seletor对象的data属性值

        response.extract_first()        提取seletor列表的第一个数据

5.scrapy工作原理

6. scrapy shell

         Scrapy终端,是一个交互终端,供您在未启动spider的情况下尝试及调试您的爬取代码。 其本意是用来测试提取 数据的代码,不过您可以将其作为正常的Python终端,在上面测试任何的Python代码。

        该终端是用来测试XPath或CSS表达式,查看他们的工作方式及从爬取的网页中提取的数据。 在编写您的spider时,该 终端提供了交互性测试您的表达式代码的功能,免去了每次修改后运行spider的麻烦。

        一旦熟悉了Scrapy终端后,您会发现其在开发和调试spider时发挥的巨大作用。

6.1 安装ipython

pip install ipython

6.2 使用

        安装完成后,打开命令窗口,输入命令:

scrapy shell www.baidu.com

 7. yield实例

7.1 管道封装(当当网)

 7.1.1 创建项目

         查看pycharm

 7.1.2 修改文件items.py(定义数据结构)

  1. class ScrapyDangdangItem(scrapy.Item):
  2. # define the fields for your item here like:
  3. # name = scrapy.Field()
  4. # 通俗的说就是你要下载的数据有什么
  5. # 爬取图片
  6. src = scrapy.Field()
  7. # 名字
  8. name = scrapy.Field()
  9. # 价格
  10. price = scrapy.Field()

7.1.3 编写爬虫代码(dang.py)

  1. import scrapy
  2. class DangSpider(scrapy.Spider):
  3. name = 'dang'
  4. allowed_domains = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']
  5. # http://category.dangdang.com/ 我默认链接最后的斜杆删除,要之后获取不到数据
  6. start_urls = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']
  7. def parse(self, response):
  8. # pipelines 下载数据
  9. # items 定义数据结构的
  10. # src = //ul[@id="component_59"]/li//img/@src
  11. # alt = //ul[@id="component_59"]/li//img/@alt
  12. # price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()
  13. # 所有的seletor的对象 都可以再次调用xpath方法
  14. li_list = response.xpath('//ul[@id="component_59"]/li')
  15. print("=======================")
  16. for li in li_list:
  17. # 第一张图片和其他的图片的标签属性是不一样的
  18. # 第一张图片的src是可以使用的,其他图片的地址是data-original
  19. src = li.xpath('.//img/@data-original').extract_first()
  20. if src:
  21. src = src
  22. else:
  23. src = li.xpath('.//img/@src').extract_first()
  24. name = li.xpath('.//img/@alt').extract_first()
  25. price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
  26. print(src,name,price)

        命令窗口运行命令:scrapy crawl dang 可以查看到下面界面。

 7.1.4 保存并且下载我们刚才爬取到的数据。

        首先,我们需要在settings.py文件中打开管道的设置。

         其次,编写文件dang.py

  1. import scrapy
  2. from scrapy_dangdang.items import ScrapyDangdangItem
  3. class DangSpider(scrapy.Spider):
  4. name = 'dang'
  5. allowed_domains = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']
  6. # http://category.dangdang.com/ 我默认链接最后的斜杆删除,要之后获取不到数据
  7. start_urls = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']
  8. def parse(self, response):
  9. # pipelines 下载数据
  10. # items 定义数据结构的
  11. # src = //ul[@id="component_59"]/li//img/@src
  12. # alt = //ul[@id="component_59"]/li//img/@alt
  13. # price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()
  14. # 所有的seletor的对象 都可以再次调用xpath方法
  15. li_list = response.xpath('//ul[@id="component_59"]/li')
  16. print("=======================")
  17. for li in li_list:
  18. # 第一张图片和其他的图片的标签属性是不一样的
  19. # 第一张图片的src是可以使用的,其他图片的地址是data-original
  20. src = li.xpath('.//img/@data-original').extract_first()
  21. if src:
  22. src = src
  23. else:
  24. src = li.xpath('.//img/@src').extract_first()
  25. name = li.xpath('.//img/@alt').extract_first()
  26. price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
  27. # 爬取到的数据放到对象里面
  28. book = ScrapyDangdangItem(src=src,name=name,price=price)
  29. # yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。
  30. # 获取一个book就将book交给pipelines(管道)
  31. yield book

        最后,我们编写文件pipelines.py

  1. # Define your item pipelines here
  2. #
  3. # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  4. # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
  5. # useful for handling different item types with a single interface
  6. from itemadapter import ItemAdapter
  7. # 如果想使用管道的话 那么就必须在settings中开启管道
  8. class ScrapyDangdangPipeline:
  9. # 在爬虫文件开始之前就执行的方法
  10. def open_spider(self,spider):
  11. self.fp = open('book.json','w',encoding='utf-8')
  12. # item就是yield后面的book对象
  13. def process_item(self, item, spider):
  14. # 以下这种模式不推荐 因为每次传递过来一个对象那么就打开一次文件 文件的操作的过于频繁
  15. #
  16. #
  17. # # 1.write方法必须要写一个字符串,而不能是其他对象
  18. # # 2.w模式 会每一个对象都打开一次文件 覆盖之前的内容
  19. # with open('book.json','a',encoding='utf-8')as fp:
  20. # fp.write(str(item))
  21. self.fp.write(str(item))
  22. return item
  23. # 在爬虫文件结束之后就执行的方法
  24. def close_spider(self,spider):
  25. self.fp.close()

        此时,我们在命令窗口使用命令(scrapy crawl dang)运行向,项目时,就可在项目中看到爬取的数据所在的文件了。

7.2 多条管道下载

        在上面代码的基础上修改文件 pipelines.py

  1. # Define your item pipelines here
  2. #
  3. # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  4. # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
  5. # useful for handling different item types with a single interface
  6. from itemadapter import ItemAdapter
  7. # 如果想使用管道的话 那么就必须在settings中开启管道
  8. class ScrapyDangdangPipeline:
  9. # 在爬虫文件开始之前就执行的方法
  10. def open_spider(self,spider):
  11. self.fp = open('book.json','w',encoding='utf-8')
  12. # item就是yield后面的book对象
  13. def process_item(self, item, spider):
  14. # 以下这种模式不推荐 因为每次传递过来一个对象那么就打开一次文件 文件的操作的过于频繁
  15. #
  16. #
  17. # # 1.write方法必须要写一个字符串,而不能是其他对象
  18. # # 2.w模式 会每一个对象都打开一次文件 覆盖之前的内容
  19. # with open('book.json','a',encoding='utf-8')as fp:
  20. # fp.write(str(item))
  21. self.fp.write(str(item))
  22. return item
  23. # 在爬虫文件结束之后就执行的方法
  24. def close_spider(self,spider):
  25. self.fp.close()
  26. import urllib.request
  27. # 多条管道开启 下载图片
  28. # 1.定义管道类
  29. # 2.在settings中开启管道 'scrapy_dangdang.pipelines.DangDangDownloadPipeline':301
  30. class DangDangDownloadPipeline:
  31. def process_item(self, item, spider):
  32. url = 'http:' + item.get('src')
  33. filename ='./books/' + item.get('name') + '.jpg'
  34. urllib.request.urlretrieve(url=url,filename=filename)
  35. return item

        其次配置文件settings.py

         在项目的spiders目录下面新建文件夹book,然后使用命令(scrapy crawl dang)运行项目时,就可在项目中看到爬取的数据所在的文件了。

 7.3 多网页下载

        编写文件dang.py

  1. import scrapy
  2. from scrapy_dangdang.items import ScrapyDangdangItem
  3. class DangSpider(scrapy.Spider):
  4. name = 'dang'
  5. # 如果多也下载的话,那么必须要调整的是allowed_domains 的范围 一般情况下只写域名
  6. allowed_domains = ['category.dangdang.com']
  7. # http://category.dangdang.com/ 我默认链接最后的斜杆删除,要之后获取不到数据
  8. start_urls = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']
  9. base_url = 'http://category.dangdang.com/pg'
  10. page = 1
  11. def parse(self, response):
  12. # pipelines 下载数据
  13. # items 定义数据结构的
  14. # src = //ul[@id="component_59"]/li//img/@src
  15. # alt = //ul[@id="component_59"]/li//img/@alt
  16. # price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()
  17. # 所有的seletor的对象 都可以再次调用xpath方法
  18. li_list = response.xpath('//ul[@id="component_59"]/li')
  19. print("=======================")
  20. for li in li_list:
  21. # 第一张图片和其他的图片的标签属性是不一样的
  22. # 第一张图片的src是可以使用的,其他图片的地址是data-original
  23. src = li.xpath('.//img/@data-original').extract_first()
  24. if src:
  25. src = src
  26. else:
  27. src = li.xpath('.//img/@src').extract_first()
  28. name = li.xpath('.//img/@alt').extract_first()
  29. price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
  30. # 爬取到的数据放到对象里面
  31. book = ScrapyDangdangItem(src=src,name=name,price=price)
  32. # yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。
  33. # 获取一个book就将book交给pipelines(管道)
  34. yield book
  35. # 每一页的爬取业务逻辑全都是一样的,所以我们只需要将执行的那个页的请求再次调用parse方法即可
  36. # 第二页请求:http://category.dangdang.com/pg2-cp01.01.02.00.00.00.html
  37. # 第二三请求:http://category.dangdang.com/pg3-cp01.01.02.00.00.00.html
  38. if self.page < 100:
  39. self.page = self.page+1
  40. url = self.base_url + str(self.page) + '-cp01.01.02.00.00.00.html'
  41. # 怎么去调用parse方法
  42. # scrapy.Request就是scrapy的get请求
  43. # url就是请求地址 callback就是你要执行的那个函数,主意不需要加圆括号
  44. yield scrapy.Request(url=url,callback=self.parse)

        使用命令(scrapy crawl dang)运行项目时,就可在项目中看到爬取的数据所在的文件了。

 7.4 一个item包含多级页面的数据(电影天堂)

        按照上面方法新建项目

         items.py——定义数据结构

  1. import scrapy
  2. class ScrapyMovieItem(scrapy.Item):
  3. # define the fields for your item here like:
  4. # name = scrapy.Field()
  5. name = scrapy.Field()
  6. src = scrapy.Field()

        修改配置文件——settings.py

        编写管道——pipelines.py

  1. class ScrapyMoviePipeline:
  2. def open_spider(self,spider):
  3. self.fp = open('movie.json','w',encoding='utf-8')
  4. def process_item(self, item, spider):
  5. self.fp.write(str(item))
  6. return item
  7. def close_spider(self,spider):
  8. self.fp.close()
'
运行

        编写爬虫代码——mv.py

  1. import scrapy
  2. from scrapy_movie.items import ScrapyMovieItem
  3. class MvSpider(scrapy.Spider):
  4. name = 'mv'
  5. allowed_domains = ['www.ygdy8.net']
  6. start_urls = ['https://www.ygdy8.net/html/gndy/china/index.html']
  7. def parse(self, response):
  8. # 要第一页的电影名字 和第二页相对应电影的图片
  9. a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')
  10. print('==============================')
  11. for a in a_list:
  12. # 获取第一页的name 和 要点击的链接
  13. name = a.xpath('./text()').extract_first()
  14. href = a.xpath('./@href').extract_first()
  15. # 第二页的地址
  16. url = 'https://www.ygdy8.net' + href
  17. # 对第二页的链接发起访问 meta表示传递给parse_second方法的数据
  18. yield scrapy.Request(url=url,callback=self.parse_second,meta={'name':name})
  19. def parse_second(self,response):
  20. # 注意 如果拿不到数据的情况下 一定要检查xpath语法是否正确
  21. src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
  22. # 接收到请求的那个meta参数的值
  23. name = response.meta['name']
  24. movie = ScrapyMovieItem(src = src,name = name)
  25. yield movie

         使用命令(scrapy crawl mv)运行项目时,就可在项目中看到爬取的数据所在的文件了。

 8 CrawlSpider(读书网

        CrawlSpider可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发送请求。所以,如果有需要跟进链接的需求,意思就是爬取了网页之后,需要提取链接再次爬取,使用CrawlSpider是非常合适的

        创建项目,创建爬虫文件

  1. scrapy startproject scrapy_readbook
  2. cd scrapy_readbook\scrapy_readbook\spiders
  3. scrapy genspider -t crawl read https://www.dushu.com/book/1188.html

       items.py——定义数据结构

  1. import scrapy
  2. class ScrapyReadbookItem(scrapy.Item):
  3. # define the fields for your item here like:
  4. # name = scrapy.Field()
  5. name = scrapy.Field()
  6. src = scrapy.Field()

        修改配置文件——settings.py

        编写管道——pipelines.py

  1. class ScrapyReadbookPipeline:
  2. def open_spider(self, spider):
  3. self.fp = open('book.json', 'w', encoding='utf-8')
  4. def process_item(self, item, spider):
  5. self.fp.write(str(item))
  6. return item
  7. def close_spider(self, spider):
  8. self.fp.close()
'
运行

        编写爬虫代码——read.py

  1. import scrapy
  2. from scrapy.linkextractors import LinkExtractor
  3. from scrapy.spiders import CrawlSpider, Rule
  4. from scrapy_readbook.items import ScrapyReadbookItem
  5. class ReadSpider(CrawlSpider):
  6. name = 'read'
  7. allowed_domains = ['www.dushu.com']
  8. start_urls = ['https://www.dushu.com/book/1188_1.html']
  9. rules = (
  10. Rule(LinkExtractor(allow=r'/book/1188_\d+\.html'),
  11. callback='parse_item',
  12. follow=False),
  13. )
  14. def parse_item(self, response):
  15. img_list = response.xpath('//div[@class="bookslist"]//img')
  16. for img in img_list:
  17. name = img.xpath('./@alt').extract_first()
  18. src = img.xpath('./@data-original').extract_first()
  19. book = ScrapyReadbookItem(name=name,src=src)
  20. yield book

        使用命令(scrapy crawl read)运行项目时,就可在项目中看到爬取的数据所在的文件了。

9 数据入库 (读书网) 

       在上面项目(读书网)基础上,继续完善实现数据入库的操作。

         为了更好的模拟生产环境,这里使用虚拟机中的数据库,数据库安装教程可以参考:linux环境安装mysql8.0以及使用Navicat连接Linux中的mysql_朂後 哋箹萣的博客-CSDN博客

        新建数据库,并且创建表

  1. mysql -uroot -p自己密码
  2. create database spider01 charset=utf8;
  3. use spider01;
  4. create table book(id int primary key auto_increment,name varchar(128),src varchar(128));

        同时也可可以使用xshell连接数据库,这样方便之后的数据查看。 

         本虚拟机ip为192.168.10.102。准备工作完成。

        修改配置文件——settings.py

  1. DB_HOST = '192.168.10.102'
  2. # 端口号是一个整数
  3. DB_PORT = 3306
  4. DU_USER = 'root'
  5. DB_PASSWORD = '1171127310'
  6. DB_NAME = 'spider01'
  7. # utf-8的-不允许写
  8. DB_CHARSET = 'utf8'
'
运行

          编写管道——pipelines.py,并且配置进settings.py中(如上图)

  1. # Define your item pipelines here
  2. #
  3. # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  4. # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
  5. # useful for handling different item types with a single interface
  6. from itemadapter import ItemAdapter
  7. class ScrapyReadbookPipeline:
  8. def open_spider(self, spider):
  9. self.fp = open('book.json', 'w', encoding='utf-8')
  10. def process_item(self, item, spider):
  11. self.fp.write(str(item))
  12. return item
  13. def close_spider(self, spider):
  14. self.fp.close()
  15. # 加载settings文件
  16. from scrapy.utils.project import get_project_settings
  17. import pymysql
  18. class MysqlPipeline:
  19. def open_spider(self,spider):
  20. settings = get_project_settings()
  21. self.host = settings['DB_HOST']
  22. self.port = settings['DB_PORT']
  23. self.user = settings['DU_USER']
  24. self.password = settings['DB_PASSWORD']
  25. self.name = settings['DB_NAME']
  26. self.charset = settings['DB_CHARSET']
  27. self.connect()
  28. def connect(self):
  29. self.conn = pymysql.connect(
  30. host=self.host,
  31. port=self.port,
  32. user=self.user,
  33. password=self.password,
  34. db=self.name,
  35. charset=self.charset
  36. )
  37. self.cursor = self.conn.cursor()
  38. def process_item(self, item, spider):
  39. sql = 'insert into book(name,src) values("{}","{}")'.format(item['name'],item['src'])
  40. # 执行sql语句
  41. self.cursor.execute(sql)
  42. # 提交
  43. self.conn.commit()
  44. return item
  45. def close_spider(self,spider):
  46. self.cursor.close()
  47. self.conn.close()

        上面文件pipelines.py中使用到了pymysql,若没有安装,安装步骤为:cmd进入到python安装目录下的Scripts下,使用下面命令安装即可使用。

pip install pymysql -i https://pypi.douban.com/simple

         使用命令(scrapy crawl read)运行项目时,就可在项目中看到爬取的数据所在的文件了,同时打开数据库可以看到爬取的数据存放到数据库表中了。

        此时,该项目完成了把读书网前13页数据爬取下来并且保存在数据库中的操作,若想把所有的书都爬取下来保存在数据库中,我们此时只需要修改文件read.py即可。

10 日志信息和日志等级

        创建项目,创建爬虫文件

         修改settings.py文件

11 scrapypost请求 (百度翻译)

        创建项目,创建爬虫文件

         编写爬虫代码——testpost.py

  1. import scrapy
  2. import json
  3. class TestpostSpider(scrapy.Spider):
  4. name = 'testpost'
  5. allowed_domains = ['fanyi.baidu.com']
  6. # post请求 如果没有参数 那么这个请求将没有任何意义
  7. # 所以start_urls 也没有用
  8. # 所以parse也没有用
  9. # start_urls = ['http://fanyi.baidu.com/']
  10. #
  11. # def parse(self, response):
  12. # pass
  13. def start_requests(self):
  14. url = 'https://fanyi.baidu.com/sug'
  15. data = {
  16. 'kw': 'final'
  17. }
  18. yield scrapy.FormRequest(url=url,formdata=data,callback=self.parse_second)
  19. def parse_second(self,response):
  20. content = response.text
  21. print('===========================')
  22. obj = json.loads(content)
  23. print(obj)

        运行效果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/819428
推荐阅读
相关标签
  

闽ICP备14008679号