scrapy连接MySQL数据库爬取英雄联盟英雄传记
作为一位对联盟游戏的爱好者,学习爬虫的时候也以这款游戏作为对象。
这个项目使用的python版本:3.6.0,scrapy使用的版本:1.11。参照这篇博客即便是不会爬虫的小白也可以带你做出一个完整的scrapy项目。废话不多说现在就开始吧。
这里是github地址:GitHub
第一步:新建一个scrapy项目
scrapy startproject LOL
使用Windows PowerShell 执行这条命令,将会在当前的路径下新建一个LOL项目。出现一个LOL文件夹,LOL的目录结构如下:
LOL--LOL--__pycache__
| | --spiders--__pycache__
| | |--__init__.py
| | --__init__.py
| | --items.py
| | --middlewares.py
| | --pipelines.py
| | --setting.py
|--scrapy.cfg
清楚目录结构后简单的介绍一下文件的作用:
- spiders文件夹 就是放你写的小爬虫的。
items.py文件 Item 是保存爬取到的数据的容器;其使用方法和python字典类似, 并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。类似在ORM中做的一样,您可以通过创建一个
scrapy.Item
类, 并且定义类型为scrapy.Field
的类属性来定义一个Item。middlewares.py文件 在我们爬虫的时候用到的中间件。
pipelines.py文件 管道。
- setting.py文件 spider的配置文件。
第二步:开始写我们的爬虫项目
1.Spiders
首先是我们的爬虫spiders文件。写一个继承scrapy.Spider的爬虫LOLSpider。
import scrapy
from LOL.items import LolItem
import reclass LOLSpider(scrapy.Spider):def get_start_urls():lol_summoner="Aatrox,Ahri,Akali,Alistar,Amumu,Anivia,Annie,Ashe,AurelionSol,Azir,Bard,Blitzcrank,Brand,Braum,Caitlyn,Camille,Cassiopeia,Chogath,Corki,Darius,Diana,Draven,DrMundo,Ekko,Elise,Evelynn,Ezreal,Fiddlesticks,Fiora,Fizz,Galio,Gangplank,Garen,Gnar,Gragas,Graves,Hecarim,Heimerdinger,Illaoi,Irelia,Ivern,Janna,JarvanIV,Jax,Jayce,Jhin,Jinx,Kalista,Karma,Karthus,Kassadin,Katarina,Kayle,Kayn,Kennen,Khazix,Kindred,Kled,KogMaw,Leblanc,LeeSin,Leona,Lissandra,Lucian,Lulu,Lux,Malphite,Malzahar,Maokai,MasterYi,MissFortune,MonkeyKing,Mordekaiser,Morgana,Nami,Nasus,Nautilus,Nidalee,Nocturne,Nunu,Olaf,Orianna,Ornn,Pantheon,Poppy,Quinn,Rakan,Rammus,RekSai,Renekton,Rengar,Riven,Rumble,Ryze,Sejuani,Shaco,Shen,Shyvana,Singed,SionSivir,Skarner,Sona,Soraka,Swain,Syndra,TahmKench,Taliya,Talon,Taric,Teemo,Thresh,Tristana,Trundle,Tryndamere,TwistedFate,Twitch,Udyr,Urgot,Varus,Vayne,Veigar,Velkoz,Vi,Viktor,Vladimir,Volibear,Warwick,Xayah,Xerath,XinZhao,Yasuo,Yorick,Zac,Zed,Ziggs,Zilean,Zoe,Zyra"# lol_summoner = "Janna"lol_summoner = lol_summoner.split(",")start_urls = []for summoner in lol_summoner:url = "http://yz.lol.qq.com/zh_CN/story/champion/"summoner = url + summoner + "/"start_urls.append(summoner)return start_urlsname = "lol_hero_story"allowed_domains = ["http://yz.lol.qq.com/zh_CN/story/"]start_urls = get_start_urls()def parse(self, response):print("-------------------我进入《英雄联盟宇宙》界面了--------------------")lolItem = LolItem()lolItem['name'] = response.xpath('//span[@class="alt__5Tm"]/text()').extract_first() #extract_first()返回第一个元素,无结果返回Noneif response.xpath('//p[@id="CatchElement"]/p/text()').extract_first() == None:# allStory = response.xpath('//p[@id="CatchElement"]/p/text()').extract() #extract()返回结果为selector list列表summonerHtml = response.textsummonerHtml = summonerHtml.replace("\r","").replace("\n","").replace("<p>","").replace("</p>","").strip()summoner_re = r'showFirstLetterEffect__2JK">(.+?)</div>'bbb = re.compile(summoner_re , re.S)aaa = bbb.findall(summonerHtml)lolItem['story'] = aaa[0]else:lolItem['story'] = response.xpath('//p[@id="CatchElement"]/text()').extract()yield lolItemprint("-------------------我离开《英雄联盟宇宙》界面了--------------------")
其中小爬虫的名字是我们自己定义的,我暂且定义 name = "lol_hero_story" 。allowed_domains = ["http://yz.lol.qq.com/zh_CN/story/"] 。start_urls 是存放将要爬虫的网址列表。我这里封装了一个方法来存放。接下接下来就是我们对结果的解析方法 parse 。我们通过xpath或则css选择器将数据解析得到自己需要的信息。再将信息存储再自己定义的Items中。
2.items
items将暂存我们得到的name和story。
# -*- coding: utf-8 -*-# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.htmlimport scrapyclass LolItem(scrapy.Item):# define the fields for your item here like:name = scrapy.Field() #英雄名story = scrapy.Field() #英雄故事pass
需要什么字段在这里以name = scrapy.Field() 形式直接写就行。在items.py中我们可以定义多个需要存储的类似LolItems类。
3.pipelines.py
在这里pipelines.py用于连接和操作我们的数据库。
# -*- coding: utf-8 -*-# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.htmlfrom twisted.enterprise import adbapi
import MySQLdb
import MySQLdb.cursors
import codecs
import json
from logging import log
import sys# reload(sys)
# sys.setdefaultencoding('utf-8')class LolPipeline(object):@classmethoddef from_settings(cls,settings):'''1、@classmethod声明一个类方法,而对于平常我们见到的则叫做实例方法。 2、类方法的第一个参数cls(class的缩写,指这个类本身),而实例方法的第一个参数是self,表示该类的一个实例3、可以通过类来调用,就像C.f(),相当于java中的静态方法'''dbparams=dict(host=settings['MYSQL_HOST'],#读取settings中的配置db=settings['MYSQL_DBNAME'],user=settings['MYSQL_USER'],passwd=settings['MYSQL_PASSWD'],charset='utf8',#编码要加上,否则可能出现中文乱码问题cursorclass=MySQLdb.cursors.DictCursor,use_unicode=False,)dbpool=adbapi.ConnectionPool('MySQLdb',**dbparams)#**表示将字典扩展为关键字参数,相当于host=xxx,db=yyy....return cls(dbpool)#相当于dbpool付给了这个类,self中可以得到#得到连接池dbpooldef __init__(self,dbpool):self.dbpool=dbpool#process_item方法是pipeline默认调用的,进行数据库操作def process_item(self, item, spider):query=self.dbpool.runInteraction(self._conditional_update,item)#调用update的方法query.addErrback(self._handle_error,item,spider)#调用异常处理方法return item#写入数据库中def _conditional_insert(self,tx,item):print("---------------这里是你想知道的tx---------------",tx)sql="insert into testpictures(name,url) values(%s,%s)"params=(item["name"],item["story"])tx.execute(sql,params)#错误处理方法def _handle_error(self, failue, item, spider):print (failue)#查询数据库def _conditional_select(self,tx,item):print("---------------这里是测试_conditional_select方法----------------")print("---------------这里是你想知道的tx---------------",tx)sql="select count(*) from summoner"tx.execute(sql)reponse = tx.fetchall()print(reponse)#更新数据库def _conditional_update(self,tx,item):print("---------------这里是执行_conditional_update方法----------------")try:print("----------------这里是测试update-------------------")sql="update summoner set story='%s' where first_name='%s' or last_name='%s'" %(item["story"],item["name"],item["name"])n = tx.execute(sql)print(n)except expression as identifier:raise identifier
文本中解释足够清楚,在这里我就不再赘述了。
4.setting
在setting中定义我们需要连接数据库的变量。
#Mysql数据库的配置信息
MYSQL_HOST = '111.230.227.159'#腾讯云公网IP
MYSQL_DBNAME = 'lol' #数据库名字,请修改
MYSQL_USER = 'root' #数据库账号,请修改
MYSQL_PASSWD = '******' #数据库密码,请修改
MYSQL_PORT = 3306 #数据库端口
CHARSET = "utf8"
将下面这段代码的注释去掉这样我们的pipeline才会发挥作用。这个文件根据大家的项目名称不同而不同。
ITEM_PIPELINES = {'LOL.pipelines.LolPipeline': 300,
}
顺便也吧这个robots协议也给修改了吧。将True改为False。
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
5.middlewares
一个般的大型网站都有反爬虫机制,像撸啊撸这样的大型网站更不用多说了。所以我们应该封装一下自己,让自己的小爬虫像一个正常的浏览者。在这里我们就不在封装Request headers了,给大家介绍一个模拟软件。chromedriver,穿上这件圣衣就可以"为所欲为"了。
在这里就不再使用项目中的middlewares.py文件了,我们另建一个文件夹,放入我们自己的mymiddlewares.py。目录结构如下:
LOL--LOL--__pycache__
| | --spiders--__pycache__
| | |--__init__.py
| | --mymiddlewares--mymiddlewares.py
| | --__init__.py
| | --items.py
| | --middlewares.py
| | --pipelines.py
| | --setting.py
|--scrapy.cfg
文件内容如下:
from selenium import webdriver
from scrapy.http import HtmlResponse
import timeclass zhongjianjian(object):def process_request(self, request, spider):print("************woshizhongjianjian**************************");if spider.name == "lol_hero_story":print ("Chromedriver is starting...")chromedriver = "E:\chromedriver.exe"driver = webdriver.Chrome(chromedriver) #指定使用的浏览器driver.get(request.url)time.sleep(1)js = "var q=document.documentElement.scrollTop=10000" driver.execute_script(js) #可执行js,模仿用户操作。此处为将页面拉至最底端。 time.sleep(3)body = driver.page_sourceprint ("访问"+request.url)return HtmlResponse(driver.current_url, body=body, encoding='utf-8', request=request)else:return None
webdriver中用很多我们需要的圣衣,感兴趣的小伙伴们可以自己去研究下。
第三步:启动我们的爬虫
启动爬虫的命令:scrapy crawl lol_hero_story
另外说一点:数据库中存储story的字段类型需要满足我们的需要,在这里我用的时text类型。
存储成功后就是这个样子了:
最后希望可以和喜爱爬虫的小伙伴一起相互交流、共同进步。文章中有哪些不足可以提出来一起交流学习呀。
scrapy连接MySQL数据库爬取英雄联盟英雄传记相关推荐
- python3+scrapy+selenium爬取英雄联盟英雄资料
继前一篇文章用nodejs+puppeteer+chromium爬取了这个英雄资料后,在本篇同样爬这个页面,思路都差不多,只是用不同语言来实现,可作为参考,个人觉得爬虫还是nodejs比较好用,可能是 ...
- Python+scrapy+mysql实现爬取磁力链接
Python+scrapy+mysql实现爬取磁力链接 作为老司机中的一员,所以试试爬取磁力链接,看看效果咋样. 直接上代码: class torrentSpider(scrapy.Spider):n ...
- nodejs+puppeteer+chromium爬取异步数据页面(英雄联盟英雄资料列表页+详情页)
puppeteer介绍 对于静态页面的爬取是灰常简单的,一个request+cherrico即可,今天我动手对英雄联盟官网英雄资料爬取时发现英雄列表和详情页是通过js异步渲染的数据,所以就用上了这个神 ...
- scrapy链接mysql_Python+scrapy+mysql实现爬取磁力链接
Python+scrapy+mysql实现爬取磁力链接 作为老司机中的一员,所以试试爬取磁力链接,看看效果咋样. 直接上代码: class torrentSpider(scrapy.Spider): ...
- python英雄联盟脚本是什么_Python3爬取英雄联盟英雄皮肤大图实例代码
爬虫思路 初步尝试 我先查看了network,并没有发现有可用的API:然后又用bs4去分析英雄列表页,但是请求到html里面,并没有英雄列表,在英雄列表的节点上,只有"正在加载中" ...
- Python3爬取英雄联盟英雄皮肤大图
前言 之前一直想爬取LOL英雄皮肤的高清图片,最近有事,也没怎么去研究,所以,现在才去看了下,并且写了Python脚本来抓取皮肤图片.需要说明一下,这个脚本有部分英雄没有抓取到,但是具体原因,我目前还 ...
- scrapy框架爬取王者荣耀英雄数据
scrapy框架爬取王者荣耀英雄属性 爬虫工程 爬虫文件 import scrapy from theKingPro.items import ThekingproItemclass ThekingS ...
- python爬虫——爬取英雄联盟英雄基本信息
爬取英雄联盟英雄基本信息 import requests import re import pymysqldb=pymysql.connect('localhost','root','126315', ...
- 【爬虫】使用requests爬取英雄联盟英雄皮肤
使用requests爬取英雄联盟英雄皮肤 自己做的 import requestsresponse = requests.get("https://game.gtimg.cn/images/ ...
最新文章
- Spring boot 默认日志配置
- .NET 基金会项目介绍 - ReactiveUI
- 前端DEMO:网络上流行的抖音罗盘
- Ubuntu 16.04退出anaconda环境
- export default 打包_贵阳【打包扣】价格
- (转)J2EE十三个技术规范
- Layout Management
- openv 在 ubuntu(linux)上的编码编译
- Vue使用vue-aplayer实现音乐播放
- 台式计算机读不到u盘怎么回事,电脑读不出u盘怎么办
- c语言判断奇偶数的函数,c语言高手进,尽量多做点13. 定义一个函数even(),判断一个整数是否是偶数。如果是偶数返回1,否则返回0。(要求包...
- Arduino基础入门篇19—点阵屏
- 在连接至 Steam 服务器时发生了一个错误。请稍后重试。
- 送你一个励志故事——涵盖20多所互联网公司的校招C++面经
- BPM与OA的简单了解
- 24 Hour Wallpaper for Mac v4.0 5K动态桌面壁纸
- IE浏览器插件注册表位置
- 三星刷android n,三星n9008怎么刷机 三星n9008刷机图文教程
- 亿信华辰 | 2022年数据治理六大趋势盘点
- 树莓派3B+控制LCD1602显示英文或数字