Python Scrapy 项目实战 python scripy
off999 2024-12-24 15:01 38 浏览 0 评论
爬虫编写流程
首先明确 Python 爬虫代码编写的流程:先直接打开网页,找到你想要的数据,就是走一遍流程。比如这个项目我要爬取历史某一天所有比赛的赔率数据、每场比赛的比赛结果等。
那么我就先打开这个网址:https://live.leisu.com/wanchang?date=20190606 然后点击“竞彩”,再点击“指数”,跳转到另一个网址:https://live.leisu.com/3in1-2674547,然后就看到了想要的数据:各公司主队获胜赔率1.61、1.65等。
到此为止,开始动手通过代码实现这个过程。
解析“爬虫主程序.py” :(主程序包括四个函数)
## -*- coding: utf-8 -*-
ls_url = 'https://live.leisu.com/wanchang?date='#ls历史https://live.leisu.com/wanchang?date=20190606
class LiveJiangSpider(scrapy.Spider):
name = 'FBP'
allowed_domains = ['leisu.com']
def start_requests(self):
d1='20190606' #历史的比赛
request = scrapy.http.FormRequest(ls_url + d1,callback=self.parseLs, meta={'d1': d1}) #历史的比赛
# request = scrapy.http.FormRequest(wl_url + d1,callback=self.parseWl, meta={'d1': d1})#未来的比赛
yield request
def parseLs(self,response):
d2=response.meta['d1']
sel=response.xpath
racelist=[e5.split("'") for e5 in sel('//li[@data-status="8"]/@data-id').extract()]
for raceid in racelist:#raceid=['2674547'];raceid[0]=2674547
item = PeilvItem()
sel_div=sel('//li[@data-id='+str(raceid[0])+']/div[@class="find-table layout-grid-tbody hide"]/div[@class="clearfix-row"]')
if str(sel_div.xpath('span[@class="lab-lottery"]/span[@class="text-jc"]/text()').extract()) == "[]":
item['cc']=""
else:
item['cc']=str(d2) + str(sel_div.xpath('span[@class="lab-lottery"]/span[@class="text-jc"]/text()').extract()[0])
if "周" in item['cc']:#取竞彩-周一001等
plurl='https://live.leisu.com/3in1-'+raceid[0]
request = scrapy.http.FormRequest(plurl,callback=self.parse,meta={'item':item})
yield request #并非return,yield压队列,parse函数将会被当做一个生成器使用。scrapy会逐一获取parse方法中生成的结果,并没有直接执行parse,循环完成后,再执行parse
def parse(self, response):
print('--------------into parse----------------------')
item = response.meta['item']
pv=response.xpath
pl_str = '/td[@class="bd-left"]/div[@class="begin float-left w-bar-100 bd-bottom p-b-8 color-999 m-b-8"]/span[@class="float-left col-3"]/text()'
if str(pv('//*[@data-id="5"]'+pl_str).extract())=="[]":
item['li'] = ''
else:
item['li']=pv('//*[@data-id="5"]' + pl_str).extract()[0]
if str(pv('//*[@data-id="2"]'+pl_str).extract())=="[]":
item['b5'] = ''
else:
item['b5']=pv('//*[@data-id="2"]' + pl_str).extract()[0]
yield item#程序在取得各个页面的items前,会先处理完之前所有的request队列里的请求,然后再提取items首先导入我们需要的包:
import datetime
import sys
import requests
import scrapy
import time
import json
import scrapy.http
from peilv.items import PeilvItem
from lxml import etreename = ‘FBP’是定义爬取项目名称,以便通过命令scrapy crawl FBP -o BaseData.csv获取数据。
start_requests
向 https://live.leisu.com/wanchang?date=20190606 发送请求。(你可以打开这个网址,里边是爬虫程序爬取数据的最外层网站) scrapy.http.FormRequest 方法: 第一个参数是请求的具体网址; 第二个参数是下一步调用的函数; 第三个参数 meta 是向调用函数传递的参数。
parseLs (parseWl 同理,不再重复讲解)
主要用于解析次外层网页数据。这里用 XPath 解析,也是比较容易掌握的解析方式。网页结构如下:(通过 Google 浏览器打开https://live.leisu.com/wanchang?date=20190606 然后右键点击网页空白处点击“查看网页源代码”,找到你需要爬取的核心数据部分,这里我要找每场比赛的信息,那么拷贝下来,然后以易于查看的规整方式列出,如下:)
<li class="list-item list-item-2674547 list-day-6-6 finished " data-id="2674547" data-status="8" data-eventid="2906" data-status-name="finished" data-nowtime="1559760300" data-realtime="1559764089" data-eventlevels="1" data-halftime="45,15" data-lottery="周三001,北单018," data-asian-name="name-0.25" data-daxiao-name="name-2.5" data-asian="1.125,0.25,0.78,0" data-daxiao="0.99,2.5,0.91,0" data-home-icon="8863b9e186e3580aa6dec29f19155d3a.png" data-away-icon="f84be480c54f0ff871b91fab14a36b36.png" style="height:41px;">
<div class="find-table layout-grid-tbody hide">
<div class="clearfix-row">
...
<span class="lab-round"> 0</span>
<span class="lab-lottery">
<span class="text-jc">周三001</span>
<span class="text-bd">北单018</span>
<span class="text-zc"></span>
</span>
......parseLS函数里的下边代码,用sel代表response.xpath,结合上表中 xml 中的元素:获取了比赛场次,存储到item[‘cc’]。
def parseLs(self,response):
sel=response.xpath
sel_div=sel('//li[@data-id='+str(raceid[0])+']/div[@class="find-table layout-grid-tbody hide"]/div[@class="clearfix-row"]')
if str(sel_div.xpath('span[@class="lab-lottery"]/span[@class="text-jc"]/text()').extract()) == "[]":
item['cc']=""
else:
item['cc']=str(d2) + str(sel_div.xpath('span[@class="lab-lottery"]/span[@class="text-jc"]/text()').extract()[0])此外,还要获取比赛的赔率信息,但并不在当前这个网页,而在更内层的网页中,需要从当前网页跳转。 存储赔率的内层网页为 https://live.leisu.com/3in1-2674547,不同场次的比赛只有-后边的数字是变化的,那么程序中只要循环构造对应的数字2674547就好了。发现这个数字刚好是 data-id。通过以下代码实现获取:
racelist=[e5.split("'") for e5 in sel('//li[@data-status="8"]/@data-id').extract()]
for raceid in racelist:
plurl='https://live.leisu.com/3in1-'+raceid[0]
request = scrapy.http.FormRequest(plurl,callback=self.parse,meta={'item':item})
yield request在Request中加入meta,即可将meta传递给response。再提交该网页请求到下一个函数parse。这里需要注意:parse中既返回item又生成新的request。
平时在parse中return item即可返回item,return request则生成新的request请求。如果我们将return换为yield的话即可既返回item又生成新的request。注意一旦使用了yield,那么parse方法中就不能有return了。
parse
网页结构如下:(通过Google浏览器打开https://live.leisu.com/3in1-2674547 然后右键点击网页空白处点击“查看网页源代码”,拷贝需要赔率的部分到文本文档,换行操作后如下:
<tr class="td-data td-pd-8 f-s-12 color-666 bd-top " data-id="4">
<td>
......
<td class="bd-left">
<div class="begin float-left w-bar-100 bd-bottom p-b-8 color-999 m-b-8">
<span class="float-left col-3"> 1.620 </span>
<span class="float-left col-3"> 3.600 </span>
<span class="float-left col-3"> 5.250 </span>
</div>
......通过以下代码获取赔率,首先由上一个函数parseLs通过scrapy.http.FormRequest(plurl,callback=self.parse,meta={‘item’:item})调用到下边的parse方法,传入plurl链接对应的网页内容response, 同样用response.xpath取出td中class为”bd-left”下边div中class为”begin float-left w-bar-100 bd-bottom p-b-8 color-999 m-b-8”再下边span中class为”float-left col-3”的值。
def parse(self, response):
print('--------------into parse----------------------')
item = response.meta['item']
pv=response.xpath
pl_str = '/td[@class="bd-left"]/div[@class="begin float-left w-bar-100 bd-bottom p-b-8 color-999 m-b-8"]/span[@class="float-left col-3"]/text()'
if str(pv('//*[@data-id="5"]'+pl_str).extract())=="[]":
item['li'] = ''
else:
item['li']=pv('//*[@data-id="5"]' + pl_str).extract()[0]
if str(pv('//*[@data-id="2"]'+pl_str).extract())=="[]":
item['b5'] = ''
else:
item['b5']=pv('//*[@data-id="2"]' + pl_str).extract()[0]
yield item#程序在取得各个页面的items前,会先处理完之前所有的request队列里的请求,然后再提取items再通过//*判断所有data-id为5下边的pl_str是否为空,若不为空则将其赋值给item[‘li’],其他的item赋值同理。
这里重点讲一下parse方法工作机制:因为使用的yield,而不是return。parse函数将会被当做一个生成器使用。
scrapy会逐一获取parse方法中生成的结果,如果是request则加入爬取队列,如果是item类型则使用pipeline处理,其他类型则返回错误信息。
scrapy取到第一部分的request不会立马就去发送这个request,只是把这个request放到队列里,然后接着从生成器里获取;
取尽第一部分的request,然后再获取第二部分的item,取到item了,就会放到对应的pipeline里处理;
parse()方法作为回调函数(callback)赋值给了Request,指定parse()方法来处理这些请求 scrapy.Request(url, callback=self.parse);
Request对象经过调度,执行生成 scrapy.http.response()的响应对象,并送回给parse()方法,直到调度器中没有Request(递归的思路);
程序在取得各个页面的items前,会先处理完之前所有的request队列里的请求,然后再提取items。
以上过程Scrapy引擎和调度器将负责到底。
总结
以上我们实现了一个爬虫实战项目,通过分析网页结构,借助 Scrapy 框架获取数据,为今后的数据分析做准备。
相关推荐
- 召唤系统游戏(召唤系统游戏排行)
-
亡灵进化专家:写的很不错了。猪脚可以用金属或骨头帮自己的亡灵进化升级挺有意思的。不过还没写完网游之审判:是英雄无敌类型的。不过写的很牛逼也写完了。推荐看看还有不死传说:虽然不是召唤的,主教是僵尸和吸血...
- w7系统怎么样(电脑w7系统怎么样)
-
有以下几点理由来分析为什么win7受欢迎1、Windows7有望受到企业用户认可微软目前的最大担心是:企业用户认为Windows7性能同Vista相差不大,因此不会出手购买。微软当初发布Vist...
- 无敌系统流小说(无敌系统流的小说)
-
《嫡女之花开富贵》作者:伊人睽睽简介祖父是镇国将军,贵不可言;外公是帝师,才名满天下;父母亲琴瑟和鸣,恩爱无双,无妾室插足;穿越为书香门第的嫡小姐,且无任何庶兄妹,慕兰音认为,她这一生,必将佳期如梦...
-
- 键盘上windows键是哪个键(电脑键盘上windows键是哪个)
-
一、台式机键盘。Windows键,简称“Winkey”或“Win键”,是在计算机键盘左下角Ctrl和Alt键之间的按键,台式机全尺寸键盘的主键盘区左下角和右下角各有一个,图案是MicrosoftWindows的视窗徽标。二、笔记...
-
2026-01-13 11:51 off999
-
- 桌面图标设置在哪打开(桌面图标从哪里调出)
-
1、首先来到电脑桌面,此时桌面没有任何图标,如下图所示。2、我们先右键单击任务栏,会出现工具栏,这时我们在下拉的选项里选择“快速启动”按钮。3、单击快速启动按钮后会出现如图所示情况,这时在电脑屏幕的左下方会显示很多快捷按钮,一般情况下单击快...
-
2026-01-13 10:51 off999
- windows如何进入启动项(怎么进入启动选项)
-
方法步骤如下:1.点击应用在Windows设置界面点击应用选项进入。2.选择启动在左侧分类中选择启动选项。3.点击开关点击软件后方的开关即可启动或关闭开机启动项。1、在Window的文件资...
- win11下载安装
-
一、允许安装软件1、首先点击左下角的开始按键,然后点击“settings”进入设置。2、然后点击设置中的“应用”选项。3、在点击左侧任务栏中的“应用和功能”。4、点击下拉栏,然后选择其中的“任何来源”...
- win7支持的最高配置(win7支持的最高配置是多少)
-
答案是支持win7的最高配置应该是i99900k加b365主板。 不过这套配置市面上价格偏高。这种机器比同等酷睿13代处理器的价格还要高至少一千元以上。而且就性能而言要超过i99900...
- 指令引用的内存不能为read(指令引用的0x0000000内存.该内存不能为read)
-
出现“指令引用内存不能为read”的错误可能有多种原因,包括软件冲突、驱动问题、内存质量问题等。以下是一些可能的解决方案:1.检查是否有软件冲突:尝试关闭可能冲突的软件,例如杀毒软件、优化软件等。2...
- hp1010打印机驱动程序(hp deskjet1010打印机驱动)
-
1.把光盘到电脑里然后打开光盘找到“setup.exe”双击运行。2.这里点击“不用了,谢谢,我喜欢CD安装”;下载的驱动也点这个。3.到这个一步有6个软件需要安装,不用点选直接下一步即可。4.同意服...
- 电脑黑屏怎么关机(电脑黑屏怎么关机不会伤硬盘)
-
开机按F8不动到高级选项出现在松手,选“最近一次的正确配置”回车修复,还不行按F8进入安全模式还原一下系统或重装系统(如果开机没反应,放一下电,重新插拔一下硬件,如果总是开不了机就检修一下去)。如果是...
- 应用程序无法启动0xc0000005
-
4、设备主板故障也会导致无信号,建议联系专业的维修人员上门检修。5、设备显卡手指边与手指边插槽接触不良,清理一下显卡的金手指边,重新插回去,重新固定住即可。应用程序错误0xc0000005解决方法如下...
- 移动硬盘分区方法详解(移动硬盘分区步骤)
-
1、进入管理页面将新买的移动硬盘插入计算机的USB接口,右击此电脑后选择管理。2、选择压缩卷在页面里选择“磁盘管理”,右击移动硬盘,选择“压缩卷”。3、输入压缩空间的大小输入压缩空间的大小,点击右下角...
- windows7副本不是正版影响使用吗
-
会经常弹出提示和安全警告,如果我们安装了一个非正版的windows系统,就会经常弹出此windows副本不是正版的提示,那么此windows副本不是正版有什么影响呢,其实除了视觉外,功能也会有影响。w...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
