python-scrapy(爬虫框架)
(1)scrapy是什么?
Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理 或存储历史数据等一系列的程序中
-
# (1) pip install scrapy
-
# (2) 报错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/visual-cpp-build-tools
-
# 解决1
-
# http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
-
# Twisted‑20.3.0‑cp37‑cp37m‑win_amd64.whl
-
# cp是你的python版本
-
# amd是你的操作系统的版本
-
# 下载完成之后 使用pip install twisted的路径 安装
-
# 切记安装完twisted 再次安装scrapy
-
-
# (3) 报错2 提示python -m pip install --upgrade pip
-
# 解决2 运行python -m pip install --upgrade pip
-
-
# (4) 报错3 win32的错误
-
# 解决3 pip install pypiwin32
-
-
# (5) anaconda
1.scrapy项目的创建以及运行
-
1. 创建爬虫的项目 scrapy startproject 项目的名字
-
注意:项目的名字不允许使用数字开头 也不能包含中文
-
2. 创建爬虫文件
-
要在spiders文件夹中去创建爬虫文件
-
cd 项目的名字\项目的名字\spiders
-
cd scrapy_百度_091\scrapy_百度_091\spiders
-
-
创建爬虫文件
-
scrapy genspider 爬虫文件的名字 要爬取网页
-
eg:scrapy genspider 百度 http://www.百度.com
-
一般情况下不需要添加http协议 因为start_urls的值是根据allowed_domains
-
修改的 所以添加了http的话 那么start_urls就需要我们手动去修改了
-
3. 运行爬虫代码
-
scrapy crawl 爬虫的名字
-
eg:
-
scrapy crawl 百度
1.创建scrapy项目:
终端输入 scrapy startproject 项目名称
2.项目组成:
spiders
__init__.py
自定义的爬虫文件.py ‐‐‐》由我们自己创建,是实现爬虫核心功能的文件
__init__.py
items.py ‐‐‐》定义数据结构的地方,是一个继承自scrapy.Item的类
middlewares.py ‐‐‐》中间件 代理
pipelines.py ‐‐‐》管道文件,里面只有一个类,用于处理下载数据的后续处理 默认是300 优先级,值越小优先级越高(1‐1000)
settings.py ‐‐‐》配置文件 比如:是否遵守robots 协议, User‐Agent 定义等
2. 创建爬虫文件
创建文件时,输入要爬取的网页地址
-
import scrapy
-
-
-
class BaiduSpider(scrapy.Spider):
-
# 爬虫的名字 用于运行爬虫的时候 使用的值
-
name = '百度'
-
# 允许访问的域名
-
allowed_domains = ['http://www.百度.com']
-
# 起始的url地址 指的是第一次要访问的域名
-
# start_urls 是在allowed_domains的前面添加一个http://
-
# 在 allowed_domains的后面添加一个/
-
start_urls = ['http://www.百度.com/']
-
-
# 是执行了start_urls之后 执行的方法 方法中的response 就是返回的那个对象
-
# 相当于 response = urllib.request.urlopen()
-
# response = requests.get()
-
def parse(self, response):
-
print('苍茫的天涯是我的爱')
3.运行爬虫代码
scrapy crawl 爬虫名称
注意:应在 spiders 文件夹内执行
反爬协议
scrapy项目的结构和response的属性和方法
-
1. scrapy项目的结构
-
项目名字
-
项目名字
-
spiders文件夹 (存储的是爬虫文件)
-
init
-
自定义的爬虫文件 核心功能文件 ****************
-
init
-
items 定义数据结构的地方 爬取的数据都包含哪些
-
middleware 中间件 代理
-
pipelines 管道 用来处理下载的数据
-
settings 配置文件 robots协议 ua定义等
-
-
2. response的属性和方法
-
response.text 获取的是响应的字符串
-
response.body 获取的是二进制数据
-
response.xpath 可以直接是xpath方法来解析response中的内容
-
response.extract() 提取seletor对象的data属性值
-
response.extract_first() 提取的seletor列表的第一个数据
demo
-
import scrapy
-
-
-
class TcSpider(scrapy.Spider):
-
name = 'tc'
-
allowed_domains = ['https://bj.58.com/sou/?key=前端开发']
-
start_urls = ['https://bj.58.com/sou/?key=前端开发']
-
-
def parse(self, response):
-
# 字符串
-
# content = response.text
-
# 二进制数据
-
# content = response.body
-
# print('===========================')
-
# print(content)
-
-
span = response.xpath('//div[@id="filter"]/div[@class="tabs"]/a/span')[0]
-
print('=======================')
-
print(span.extract())
demo2
-
import scrapy
-
-
-
class CarSpider(scrapy.Spider):
-
name = 'car'
-
allowed_domains = ['https://car.autohome.com.cn/price/brand-15.html']
-
# 注意如果你的请求的接口是html为结尾的 那么是不需要加/的
-
start_urls = ['https://car.autohome.com.cn/price/brand-15.html']
-
-
def parse(self, response):
-
name_list = response.xpath('//div[@class="main-title"]/a/text()')
-
price_list = response.xpath('//div[@class="main-lever"]//span/span/text()')
-
-
for i in range(len(name_list)):
-
name = name_list[i].extract()
-
price = price_list[i].extract()
-
print(name, price)
scrapy组织架构
scrapy工作原理
scrapy Shell(调试使用)
1.什么是scrapy shell?
Scrapy 终端,是一个交互终端,供您在未启动 spider 的情况下尝试及调试您的爬取代码。 其本意是用来测试提取 数据的代码,不过您可以将其作为正常的Python 终端,在上面测试任何的 Python 代码。 该终端是用来测试XPath 或 CSS 表达式,查看他们的工作方式及从爬取的网页中提取的数据。 在编写您的 spider 时,该 终端提供了交互性测试您的表达式代码的功能,免去了每次修改后运行spider 的麻烦。 一旦熟悉了Scrapy 终端后,您会发现其在开发和调试 spider 时发挥的巨大作用。
2.安装ipython
安装: pip install ipython
简介:如果您安装了 IPython , Scrapy 终端将使用 IPython ( 替代标准 Python 终端 ) 。 IPython 终端与其他相 比更为强大,提供智能的自动补全,高亮输出,及其他特性。
使用
demo
yield
1. 带有 yield 的函数不再是一个普通函数,而是一个生成器 generator ,可用于迭代
2. yield 是一个类似 return 的关键字,迭代一次遇到 yield 时就返回 yield 后面 ( 右边 ) 的值。重点是:下一次迭代 时,从上一次迭代遇到的yield 后面的代码 ( 下一行 ) 开始执行
3. 简要理解: yield 就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后 ( 下一行 ) 开始
案例:
1. 当当网 (1) yield (2) . 管道封装(3) . 多条管道下载 (4)多页数据下载 2.电影天堂 (1)一个 item 包含多级页面的数据
1.自定义核心文件
-
import scrapy
-
# 不要看他报错,不影响下面调用方法
-
# 导入 scrapy_dangdang_095 下面的items
-
# from scrapy_dangdang_095.items import ScrapyDangdang095Item
-
# 解决导入函数报错
-
from ..items import ScrapyDangdang095Item
-
-
-
class DangSpider(scrapy.Spider):
-
name = 'dang'
-
# 如果是多页下载的话 那么必须要调整的是allowed_domains的范围 一般情况下只写域名
-
allowed_domains = ['category.dangdang.com']
-
start_urls = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']
-
-
base_url = 'http://category.dangdang.com/pg'
-
page = 1
-
-
def parse(self, response):
-
# pipelines 下载数据
-
# items 定义数据结构的
-
# src = //ul[@id="component_59"]/li//img/@src
-
# alt = //ul[@id="component_59"]/li//img/@alt
-
# price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()
-
# 所有的seletor的对象 都可以再次调用xpath方法
-
li_list = response.xpath('//ul[@id="component_59"]/li')
-
-
for li in li_list:
-
# 此处 图片是懒加载 所以获取的不是src
-
src = li.xpath('.//img/@data-original').extract_first()
-
# 第一张图片和其他的图片的标签的属性是不一样的
-
# 第一张图片的src是可以使用的 其他的图片的地址是data-original
-
# 第一张 返回的是None
-
if src:
-
src = src
-
else:
-
src = li.xpath('.//img/@src').extract_first()
-
-
name = li.xpath('.//img/@alt').extract_first()
-
price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
-
-
book = ScrapyDangdang095Item(src=src, name=name, price=price)
-
-
# 获取一个book就将book交给pipelines
-
yield book
-
-
# 每一页的爬取的业务逻辑全都是一样的,所以我们只需要将执行的那个页的请求再次调用parse方法
-
# 就可以了
-
# http://category.dangdang.com/pg2-cp01.01.02.00.00.00.html
-
# http://category.dangdang.com/pg3-cp01.01.02.00.00.00.html
-
# http://category.dangdang.com/pg4-cp01.01.02.00.00.00.html
-
-
if self.page < 100:
-
self.page = self.page 1
-
-
url = self.base_url str(self.page) '-cp01.01.02.00.00.00.html'
-
-
# 怎么去调用parse方法
-
# scrapy.Request就是scrpay的get请求
-
# url就是请求地址
-
# callback是你要执行的那个函数 注意不需要加()
-
yield scrapy.Request(url=url, callback=self.parse)
2.配置items要爬取的数据
-
# Define here the models for your scraped items
-
#
-
# See documentation in:
-
# https://docs.scrapy.org/en/latest/topics/items.html
-
-
import scrapy
-
-
-
class ScrapyDangdang095Item(scrapy.Item):
-
# define the fields for your item here like:
-
# name = scrapy.Field()
-
# 通俗的说就是你要下载的数据都有什么
-
-
# 图片
-
src = scrapy.Field()
-
# 名字
-
name = scrapy.Field()
-
# 价格
-
price = scrapy.Field()
-
3.使用管道 pipelines
-
# Define your item pipelines here
-
#
-
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
-
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
-
-
-
# useful for handling different item types with a single interface
-
from itemadapter import ItemAdapter
-
-
-
# 如果想使用管道的话 那么就必须在settings中开启管道
-
class ScrapyDangdang095Pipeline:
-
# 在爬虫文件开始的之前就执行的一个方法
-
def open_spider(self, spider):
-
self.fp = open('book.json', 'w', encoding='utf-8')
-
-
# item就是yield后面的book对象
-
def process_item(self, item, spider):
-
# 以下这种模式不推荐 因为每传递过来一个对象 那么就打开一次文件 对文件的操作过于频繁
-
-
# # (1) write方法必须要写一个字符串 而不能是其他的对象
-
# # (2) w模式 会每一个对象都打开一次文件 覆盖之前的内容
-
# with open('book.json','a',encoding='utf-8')as fp:
-
# fp.write(str(item))
-
# 请使用此方法
-
self.fp.write(str(item))
-
-
return item
-
-
# 在爬虫文件执行完之后 执行的方法
-
def close_spider(self, spider):
-
self.fp.close()
-
-
-
import urllib.request
-
-
-
# 多条管道开启,下载图片
-
# (1) 定义管道类
-
# (2) 在settings中开启管道
-
# 'scrapy_dangdang_095.pipelines.DangDangDownloadPipeline':301
-
class DangDangDownloadPipeline:
-
def process_item(self, item, spider):
-
url = 'http:' item.get('src')
-
filename = './books/' item.get('name') '.jpg'
-
-
urllib.request.urlretrieve(url=url, filename=filename)
-
-
return item
注意:要是用pipelines 要在settings 中开启
获取列表和详情
详情地址
-
import scrapy
-
-
from ..items import ScrapyMovie099Item
-
-
-
class MvSpider(scrapy.Spider):
-
name = 'mv'
-
allowed_domains = ['www.dytt8.net']
-
start_urls = ['https://www.dytt8.net/html/gndy/china/index.html']
-
-
def parse(self, response):
-
# 要第一个的名字 和 第二页的图片
-
a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')
-
-
for a in a_list:
-
# 获取第一页的name 和 要点击的链接
-
name = a.xpath('./text()').extract_first()
-
href = a.xpath('./@href').extract_first()
-
-
# 第二页的地址是
-
url = 'https://www.dytt8.net' href
-
-
# 对第二页的链接发起访问
-
yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})
-
-
def parse_second(self, response):
-
# 注意 如果拿不到数据的情况下 一定检查你的xpath语法是否正确
-
# 详情页src
-
src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
-
# 接受到请求的那个meta参数的值,外页面列表name
-
name = response.meta['name']
-
-
movie = ScrapyMovie099Item(src=src, name=name)
-
# 发给管道
-
yield movie
CrawlSpider
1. 继承自 scrapy.Spider
2. 独门秘笈
CrawlSpider 可以定义规则,再解析 html 内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发 送请求
所以,如果有需要跟进链接的需求,意思就是爬取了网页之后,需要提取链接再次爬取,使用 CrawlSpider 是非常 合适的
运行原理
CrawlSpider案例
1.创建项目:scrapy startproject dushuproject
2.跳转到spiders路径 cd\dushuproject\dushuproject\spiders
注意:此处多了一个 ‐t crawl
3.创建爬虫类:scrapy genspider ‐t crawl read www.dushu.com
demo
自定义核心文件
-
import scrapy
-
from scrapy.linkextractors import LinkExtractor
-
from scrapy.spiders import CrawlSpider, Rule
-
-
from ..items import ScrapyReadbook101Item
-
-
-
class ReadSpider(CrawlSpider):
-
name = 'read'
-
allowed_domains = ['www.dushu.com']
-
# 注意第一页的数据1188_1 中的_1 不要漏掉
-
start_urls = ['https://www.dushu.com/book/1188_1.html']
-
# allow 提取页面符合要求所有连接
-
# follow=True 如果是false 只会获取当前显示页的所有数据 13 页
-
# follow=True 会获取全部页数据
-
rules = (
-
Rule(LinkExtractor(allow=r'/book/1188_\d .html'),
-
callback='parse_item',
-
follow=True),
-
)
-
-
def parse_item(self, response):
-
-
img_list = response.xpath('//div[@class="bookslist"]//img')
-
-
for img in img_list:
-
name = img.xpath('./@data-original').extract_first()
-
src = img.xpath('./@alt').extract_first()
-
-
book = ScrapyReadbook101Item(name=name,src=src)
-
yield book
-
-
-
将查询的数据存入数据库中
需要安装 pymysql 包
pymysql 的使用步骤
1.pip install pymysql
2.pymysql.connect(host,port,user,password,db,charset)
3.conn.cursor()
4.cursor.execute()
2.setting配置mysql信息/以及新建通道
3.通道pipelines
-
# Define your item pipelines here
-
#
-
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
-
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
-
-
-
# useful for handling different item types with a single interface
-
from itemadapter import ItemAdapter
-
-
-
class ScrapyReadbook101Pipeline:
-
-
def open_spider(self, spider):
-
self.fp = open('book.json', 'w', encoding='utf-8')
-
-
def process_item(self, item, spider):
-
self.fp.write(str(item))
-
return item
-
-
def close_spider(self, spider):
-
self.fp.close()
-
-
-
# 加载settings文件
-
from scrapy.utils.project import get_project_settings
-
import pymysql
-
-
-
class MysqlPipeline:
-
-
def open_spider(self, spider):
-
settings = get_project_settings()
-
self.host = settings['DB_HOST']
-
self.port = settings['DB_PORT']
-
self.user = settings['DB_USER']
-
self.password = settings['DB_PASSWROD']
-
self.name = settings['DB_NAME']
-
self.charset = settings['DB_CHARSET']
-
-
self.connect()
-
-
def connect(self):
-
self.conn = pymysql.connect(
-
host=self.host,
-
port=self.port,
-
user=self.user,
-
password=self.password,
-
db=self.name,
-
charset=self.charset
-
)
-
-
self.cursor = self.conn.cursor()
-
-
def process_item(self, item, spider):
-
sql = 'insert into book(name,src) values("{}","{}")'.format(item['name'], item['src'])
-
# 执行sql语句
-
self.cursor.execute(sql)
-
# 提交
-
self.conn.commit()
-
-
return item
-
-
def close_spider(self, spider):
-
self.cursor.close()
-
self.conn.close()
日志信息和日志等级
scrapy的post请求
自定义核心文件
-
import scrapy
-
-
import json
-
-
-
class TestpostSpider(scrapy.Spider):
-
name = 'testpost'
-
allowed_domains = ['https://fanyi.百度.com/sug']
-
-
# post请求 如果没有参数 那么这个请求将没有任何意义
-
# 所以start_urls 也没有用了
-
# parse方法也没有用了
-
# start_urls = ['https://fanyi.百度.com/sug/']
-
#
-
# def parse(self, response):
-
# pass
-
-
def start_requests(self):
-
url = 'https://fanyi.百度.com/sug'
-
-
data = {
-
'kw': 'final'
-
}
-
-
yield scrapy.FormRequest(url=url, formdata=data, callback=self.parse_second)
-
-
def parse_second(self, response):
-
content = response.text
-
# json 不需要 ,encoding='utf-8'
-
obj = json.loads(content)
-
-
print(obj)
代理
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfifgf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13