一、scrapy框架的安装
pip install scrapy
可能找不到win32api模块 ---windows系统中常见
pip install pypiwin32
二、scrapy框架的使用
2.1 新建项目
scrapy startproject xxx
items.py ------ 要抓取的字段
pipelines.py -------- 用于编写数据存储等逻辑
settings -------- 项目的设置文件
创建爬虫文件 会在spiders下生成一个爬虫名称的py文件
scrapy genspider 爬虫名称 域名
spiders下的命名的爬虫名称文件
import scrapy
class XiaoSpider(scrapy.Spider):
name = 'xiao' # 爬虫名字
allowed_domains = ['4399.com'] # 允许爬取的域名
start_urls = ['http://4399.com/'] # 起始页面url
def parse(self, response): # 该方法默认处理解析
pass
2.2 运行爬虫文件
scrapy crawl 爬虫名称
可以在建一个main.py,运行爬虫文件
from scrapy import cmdline
# 在scrapy项目里面,为了方便运行scrapy项目时候创建的文件
# cmdline.execute
#
cmdline.execute('scrapy crawl 爬虫名字'.split())
2.3 爬虫流程
1. 创建项目
scrapy startproject 项目名称
2. 进入项目
cd 项目名称
3. 创建爬虫
scrapy genspider 爬虫名字 域名
4. 可能需要修改start_urls,修改成想要抓取的页面
5. 对数据进行解析,在spider里面parse(response)方法中进行解析
def parse(self,response):
response.text 拿到页面源代码
response.xpath()
response.css()
解析数据的时候,需要注意,默认xpath()返回的是Selector对象
想要数据必须使用 extract() 提取数据
extract() 返回列表
extract_first() 返回一个数据
yield 返回数据 -> 数据交给pipelines进行持久化存储
6. 在pipelines中完成数据存储
class 类名:
def process_item(self, item, spider): # item表示数据 spider是爬虫
return item # 必须有return东西,否则下一个管道收不到数据
7. 设置settings.py文件将pipelines进行生效设置
ITEM_PIPELINES = {
# key 是管道的路径
# value 是管道的优先级 数越小,优先级越高
'game.pipelines.GamePipeline': 300,
}
8. 运行爬虫
scrapy crawl 爬虫名字
在items.py中存取要的字段:
import scrapy
class CaipiaoItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 定义保存的字段
qihao = scrapy.Field()
red_ball = scrapy.Field()
blue_ball = scrapy.Field()
爬虫文件中
import scrapy
from 爬虫开发.caipiao.caipiao.items import CaipiaoItem
class ShuangseqiuSpider(scrapy.Spider):
name = 'shuangseqiu'
allowed_domains = ['500.com']
start_urls = ['https://datachart.500.com/ssq/']
def parse(self, resp):
trs = resp.xpath('//tbody[@id="tdata"]/tr')
for tr in trs:
# 判断表中非空格
if not tr.xpath('./@class').extract_first() == 'tdbck':
red_ball = tr.xpath('./td[@class="chartBall01"]/text()').extract()
blue_ball = tr.css('.chartBall02::text').extract()
qihao = tr.xpath('./td[1]/text()').extract_first().strip()
# dic = {
# 'qihao':qihao,
# 'red_ball':red_ball,
# 'blue_ball':blue_ball
# }
# yield dic
cai = CaipiaoItem()
cai['qihao'] = qihao
cai['red_ball'] = red_ball
cai['blue_ball'] = blue_ball
yield cai
2.4 存储
1.存储到文件中
class CaipiaoPipeline: def open_spider(self,spider): self.f = open('./双色球.csv',mode='a',encoding='utf-8') def close_spider(self,spider): if self.f: self.f.close() def process_item(self, item, spider): self.f.write(f'{item["qihao"]},{"_".join(item["red_ball"])},{item["blue_ball"]}\n') return item
2.存储到mysql中
class CaipiaoMySqlPipeline: def open_spider(self,spider): __config = { 'host': 'localhost', 'port': 3306, 'user': 'root', 'password': 'a123456', 'database': 'spider', 'auth_plugin': 'mysql_native_password' } self.conn = mysql.connector.pooling.MySQLConnectionPool(**__config,pool_size=10).get_connection() def close_spider(self,spider): if self.conn: self.conn.close() def process_item(self, item, spider): try: cursor = self.conn.cursor() sql = 'insert into caipiao(qihao,red_ball,blue_ball) values (%s,%s,%s)' cursor.execute(sql,(item['qihao'],'_'.join(item['red_ball']),item['blue_ball'])) self.conn.commit() except Exception as e: print(e) self.conn.rollback() finally: if cursor: cursor.close() return item
3.存储到mangodb中
逻辑和mysql一样
爬取图片
class BizhiSpider(scrapy.Spider):
name = 'bizhi'
allowed_domains = ['netbian.com']
start_urls = ['http://netbian.com/']
def parse(self, resp):
content = resp.xpath('//*[@id="main"]/div[4]/ul/li')
for li in content:
img_src = li.xpath('./a/@href').extract_first()
# 理论上应该开始进行网络请求,根据scrapy进行的原理,对href进行处理
if img_src:
yield scrapy.Request(url=resp.urljoin(img_src), # 把resp中的url和刚刚获取的url进行拼接整合
method='get', callback=self.parse_detail) # 回调函数,当响应回馈之后,如何响应内容
break
def parse_detail(self, resp):
pic = BizhiItem()
pic['src'] = resp.xpath('//*[@id="main"]/div[3]/div/p/a/img/@src').extract_first()
pic['title'] = resp.xpath('//*[@id="main"]/div[3]/div/p/a/img/@title').extract_first()
yield pic
管道pipelines中
from scrapy.pipelines.images import ImagesPipeline import scrapy class BizhiPipeline: def process_item(self, item, spider): print(item) return item # 想要使用ImagePipeline 必须单独使用创建一个文件夹 class BizhiSavePipeline(ImagesPipeline): # 利用图片下载管道完成数据下载操作 def get_media_requests(self, item, info): # 负责下载的 yield scrapy.Request(url=item['src']) # 直接返回请求 def file_path(self, request, response=None, info=None, *, item=None): # 准备文件路径 # resquest.url 可以直接获取到刚刚请求的url 先需要在settings中设置往项目根目录里面创 # #建文件夹 不创建ImagesPipeline无法下载图片 IMAGES_STORE = './bizhi_pic' file_name = request.url.split('/')[-1] return f'img1/{file_name}' def item_completed(self, results, item, info): # 返回文件的详细信息 可以选择用mysql存储图片本地地址 statu,finfo = results[0] item['local_path'] = finfo['path'] print(item) return item
三、设置请求头和代理ip
添加请求头
在minddleware.py里面设置
class My_useragent(object):
def process_request(self,request,spider):
agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
request.header['User-Agent'] = agent
在settings中添加
DOWNLOADER_MIDDLEWARES = {
'bizhi.middlewares.BizhiDownloaderMiddleware': 543,
'bizhi.middlewares.My_useragent': 303
}