爬虫笔记八——Scrapy实战项目
(案例一)手机App抓包爬虫
1. items.py
import scrapy
class DouyuspiderItem(scrapy.Item):
# 存储照片的名字
nickName = scrapy.Field()
# 照片的url路径
imageUrl = scrapy.Field()
# 照片保存在本地的路径
imagePath = scrapy.Field()
items
2. spiders/douyu.py
# -*- coding: utf-8 -*-
import scrapy
from douyuSpider.items import DouyuspiderItem
import json
class DouyuSpider(scrapy.Spider):
name = 'douyu'
allowed_domains = ['capi.douyucdn.cn']
offset = 0
url = "http://capi.douyucdn.cn/api/v1/getVerticalRoom?limit=20&offset="
start_urls = [url + str(offset)]
def parse(self, response):
data = json.loads(response.body)["data"]
for each in data:
item = DouyuspiderItem()
item["nickName"] = each["nickname"]
item["imageUrl"] = each["vertical_src"]
yield item
self.offset += 20
nextUrl = re.sub('offset=\d+', 'offset='+str(self.offset), response.url)
yield scrapy.Request(nextUrl, callback=self.parse)
spiders/douyu.py
3. 设置setting.py
DEFAULT_REQUEST_HEADERS = {
'User-Agent': 'News 6.6.5 rv:6.6.5.03 (iPhone; iOS 11.2.6; zh_CN) Cronet'
}
ITEM_PIPELINES = {
'douyuSpider.pipelines.DouyuspiderPipeline': 300,
}
IMAGES_STORE = 'E:\Python\Spider\day05\douyuSpider\images'
# 日志文件名和处理等级
LOG_FILE = "douyu.log"
LOG_LEVEL = "DEBUG"
setting
4. pipelines.py
# -*- coding: utf-8 -*-
import scrapy
from scrapy.exceptions import DropItem
from scrapy.utils.project import get_project_settings
from scrapy.pipelines.images import ImagesPipeline
import os
class DouyuspiderPipeline(ImagesPipeline):
IMAGES_STORE = get_project_settings().get("IMAGES_STORE")
# 根据图片的url生成图片的Request
def get_media_requests(self, item, info):
image_url = item["imageUrl"]
yield scrapy.Request(image_url)
# 图片下载完毕之后,处理结果会以二元组的方式作为results参数传递给item_completed函数
# 这个二元组定义如下:(success, image_info_or_failure),第一个元素表示图片是否下载成功,第二个元素是一个字典
# 字典的含义如下:{'url': 图片的url, 'path': 图片的存储地址,跟IMAGE_STORE相关, 'checksum': 图片的内容hash}
def item_completed(self, results, item, info):
# 如果图片下载成功,则获取图片的存储地址
image_path = [x["path"] for ok, x in results if ok]
#print image_path
if not image_path:
raise DropItem("Item contains no images")
# 修改图片的存储地址:
os.rename(self.IMAGES_STORE + "\\" + image_path[0], self.IMAGES_STORE + "\\" + item["nickName"] + ".jpg")
item["imagePath"] = self.IMAGES_STORE + "\\" + item["nickName"]
#print item["imagePath"]
return item
pipelines
5. 运行
在项目根目录下新建main.py文件,用于调试
from scrapy import cmdline
cmdline.execute("scrapy crawl douyu".split())
执行程序
python main.py
5.2. (案例二)阳光热线问政平台爬虫
阳光热线问政平台
http://wz.sun0769.com/index.php/question/questionType?type=4
爬取投诉帖子的编号、帖子的url、帖子的标题,和帖子里的内容。
import scrapy
class DongguanspiderItem(scrapy.Item):
# 每个帖子的标题
title = scrapy.Field()
# 每个帖子的编号
number = scrapy.Field()
# 每个帖子的文字内容
content = scrapy.Field()
# 每个帖子的url
url = scrapy.Field()
items.py
spiders/sunwz.py
# -*- coding: utf-8 -*-
import scrapy
from dongguanSpider.items import DongguanspiderItem class DongguanSpider(scrapy.Spider):
name = 'dongguan'
allowed_domains = ['sun0769.com']
url = 'http://wz.sun0769.com/index.php/question/questionType?type=4&page='
headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
offset = 0
start_urls = [url + str(offset)] # 解析每个页面的响应
def parse(self, response):
# 获取每页帖子的链接列表
links = response.xpath('//div[@class="greyframe"]/table//td/a[2]/@href').extract() for link in links:
# 获取每个帖子的Request请求
yield scrapy.Request(link, headers=self.headers, callback=self.parse_item) # 设置页码终止条件为最后一页的page值,
if self.offset <= 88560:
self.offset += 30
# 获取每页的Request请求
yield scrapy.Request(self.url + str(self.offset), headers=self.headers, callback=self.parse) # 解析页面里的每个帖子的响应
def parse_item(self, response):
item = DongguanspiderItem()
titleList = response.xpath('//div[contains(@class, "pagecenter p3")]//strong/text()')[0].extract().strip().split()
# 帖子的标题
item['title'] = titleList[0][3:]
# 帖子的编号
item['number'] = titleList[1][3:]
# 帖子的内容,先取出有图片帖子的内容,再取出没有图片帖子的内容
content = response.xpath('//div[@class="contentext"]/text()').extract()
if len(content) == 0:
content = response.xpath('//div[@class="c1 text14_2"]/text()').extract()
item['content'] = "".join(content).strip()
else:
item['content'] = "".join(content).strip()
# 帖子的链接地址
item['url'] = response.url
yield item
Spider版本
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from dongguanSpider.items import DongguanspiderItem class SunSpider(CrawlSpider):
name = 'sun'
allowed_domains = ['sun0769.com']
start_urls = ['http://wz.sun0769.com/index.php/question/questionType?type=4&page=']
# 每页链接的匹配规则
pageLink = LinkExtractor(allow=('type=4'))
# 每个帖子链接的匹配规则
contentLink = LinkExtractor(allow=r'/html/question/\d+/\d+.shtml') rules = (
Rule(pageLink),
Rule(contentLink, callback='parse_item')
) def parse_item(self, response):
item = DongguanspiderItem()
titleList = response.xpath('//div[contains(@class, "pagecenter p3")]//strong/text()')[
0].extract().strip().split()
# 帖子的标题
item['title'] = titleList[0][3:]
# 帖子的编号
item['number'] = titleList[1][3:]
# 帖子的内容,先取出有图片帖子的内容,再取出没有图片帖子的内容
content = response.xpath('//div[@class="contentext"]/text()').extract()
if len(content) == 0:
content = response.xpath('//div[@class="c1 text14_2"]/text()').extract()
# content为列表,通过join方法拼接字符串,并去除首尾空格
item['content'] = "".join(content).strip()
else:
item['content'] = "".join(content).strip()
# 帖子的链接地址
item['url'] = response.url
yield item
CrawlSpider 版本
pipelines.py
# -*- coding: utf-8 -*- # 文件处理类库,可以指定编码格式
import codecs
import json class DongguanspiderPipeline(object):
def __init__(self):
# 创建一个可写文件,指定编码格式为utf-8
self.filename = codecs.open('dongguan.json', 'w', encoding='utf-8') def process_item(self, item, spider):
content = json.dumps(dict(item), ensure_ascii=False) + '\n'
self.filename.write(content)
return item def spider_closed(self, spider):
self.filename.close()
pipelines.py
settings.py
ITEM_PIPELINES = {
'dongguanSpider.pipelines.DongguanspiderPipeline': 300,
}
# 日志文件名和处理等级
LOG_FILE = "dg.log"
LOG_LEVEL = "DEBUG"
settings
在项目根目录下新建main.py文件,用于调试
from scrapy import cmdline
cmdline.execute("scrapy crawl sun".split())
执行程序
py2 main.py
5.3. (案例三)新浪网页分类资讯爬虫
爬取新浪网导航页所有分类下所有大类、小类、小类里的子链接,以及子链接页面的新闻内容。
效果演示图:

items.py
import scrapy
class SinaspiderItem(scrapy.Item):
# 大类的标题
parentTitle = scrapy.Field()
# 大类的url
parentUrl = scrapy.Field()
# 小类的标题
subTitle = scrapy.Field()
# 小类的url
subUrl = scrapy.Field()
# 小类的存储路径
subDir = scrapy.Field()
# 文章的url
fileUrl = scrapy.Field()
# 文章的标题
title = scrapy.Field()
# 文章的内容
content = scrapy.Field()
spiders/sina.py
# -*- coding: utf-8 -*-
import scrapy
from sinaSpider.items import SinaspiderItem
import os
class SinaSpider(scrapy.Spider):
name = 'sina'
allowed_domains = ['sina.com.cn']
start_urls = ['http://news.sina.com.cn/guide/']
# 解析首页
def parse(self, response):
# 获取大类的标题列表
parentTitleList = response.xpath('//div[@id="tab01"]//h3/a/text()').extract()
# 获取大类的url列表
parentUrlList = response.xpath('//div[@id="tab01"]//h3/a/@href').extract()
# 遍历大类列表
for i in range(len(parentTitleList)):
# 根据大类的标题名新建目录
parentDir = '.\\Data\\' + parentTitleList[i]
if not os.path.exists(parentDir):
os.makedirs(parentDir)
# 获取每个大类下的小类的标题列表
subTitleList = response.xpath('//div[@id="tab01"]/div[{}]//li/a/text()'.format(i+1)).extract()
# 获取每个大类下的小类的url列表
subUrlList = response.xpath('//div[@id="tab01"]/div[{}]//li/a/@href'.format(i+1)).extract()
# 遍历某一个大类下的小类列表
for j in range(len(subTitleList)):
# 根据小类的标题名新建目录
subDir = parentDir + '\\'+ subTitleList[j]
if not os.path.exists(subDir):
os.makedirs(subDir)
item = SinaspiderItem()
item['parentTitle'] = parentTitleList[i]
item['parentUrl'] = parentUrlList[i]
item['subTitle'] = subTitleList[j]
item['subUrl'] = subUrlList[j]
item['subDir'] = subDir
# 发送每个小类的Request请求,在Request中加入meta,即可将meta传递给response作为参数给回调函数使用
yield scrapy.Request(item['subUrl'], meta={'meta_1': item}, callback=self.parse_news)
# 解析每个小类的url,爬取每个小类下的文章标题和链接
def parse_news(self, response):
# 获取Request请求发送的meta_1参数
meta_1 = response.meta['meta_1']
fileUrlList = response.xpath('//a/@href').re(r'.*\d+\.shtml')
for i in range(len(fileUrlList)):
item = SinaspiderItem()
item['parentTitle'] = meta_1['parentTitle']
item['parentUrl'] = meta_1['parentUrl']
item['subTitle'] = meta_1['subTitle']
item['subUrl'] = meta_1['subUrl']
item['subDir'] = meta_1['subDir']
item['fileUrl'] = fileUrlList[i]
# 发送每篇新闻的Request请求,在Request中加入meta,向回调函数parse_content传递参数meta2
yield scrapy.Request(item['fileUrl'], meta={'meta_2': item}, callback=self.parse_content)
# 解析每个新闻页,获取新闻标题和内容
def parse_content(self, response):
# 获取Request请求发送的meta_2参数
item = response.meta['meta_2']
# 获取新闻的标题
title = response.xpath('//h1[@class="main-title"]/text()')[0].extract()
content = ''
contentList = response.xpath('//div[@class="article"]/p/text()').extract()
# 获取新闻的内容
for content_one in contentList:
content += content_one
item['title'] = title
item['content'] = content
yield item
items
pipelines.py
class SinaspiderPipeline(object):
def process_item(self, item, spider):
fileUrl = item['fileUrl']
# 根据新闻链接地址命名存储新闻的文件名
fileName = item['subDir'] + '\\' + fileUrl[7:-6].replace('/', '_') + '.txt'
with open(fileName, 'w') as f:
f.write(item['content'].encode('utf-8'))
return item
piplines
settings.py
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"
ITEM_PIPELINES = {
'sinaSpider.pipelines.SinaspiderPipeline': 300,
}
# 日志文件名和处理等级
LOG_FILE = "sina.log"
LOG_LEVEL = "DEBUG"
settings
在项目根目录下新建main.py文件,用于调试
from scrapy import cmdline
cmdline.execute("scrapy crawl sina".split())
执行程序
py2 main.py
爬虫笔记八——Scrapy实战项目的更多相关文章
- Python分布式爬虫开发搜索引擎 Scrapy实战视频教程
点击了解更多Python课程>>> Python分布式爬虫开发搜索引擎 Scrapy实战视频教程 课程目录 |--第01集 教程推介 98.23MB |--第02集 windows下 ...
- PYTHON 爬虫笔记十一:Scrapy框架的基本使用
Scrapy框架详解及其基本使用 scrapy框架原理 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...
- PYTHON 爬虫笔记八:利用Requests+正则表达式爬取猫眼电影top100(实战项目一)
利用Requests+正则表达式爬取猫眼电影top100 目标站点分析 流程框架 爬虫实战 使用requests库获取top100首页: import requests def get_one_pag ...
- Scrapy:学习笔记(2)——Scrapy项目
Scrapy:学习笔记(2)——Scrapy项目 1.创建项目 创建一个Scrapy项目,并将其命名为“demo” scrapy startproject demo cd demo 稍等片刻后,Scr ...
- Scrapy实战-新浪网分类资讯爬虫
项目要求: 爬取新浪网导航页所有下所有大类.小类.小类里的子链接,以及子链接页面的新闻内容. 什么是Scrapy框架: Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应 ...
- Python实战项目网络爬虫 之 爬取小说吧小说正文
本次实战项目适合,有一定Python语法知识的小白学员.本人也是根据一些网上的资料,自己摸索编写的内容.有不明白的童鞋,欢迎提问. 目的:爬取百度小说吧中的原创小说<猎奇师>部分小说内容 ...
- scrapy爬虫笔记(三)------写入源文件的爬取
开始爬取网页:(2)写入源文件的爬取 为了使代码易于修改,更清晰高效的爬取网页,我们将代码写入源文件进行爬取. 主要分为以下几个步骤: 一.使用scrapy创建爬虫框架: 二.修改并编写源代码,确定我 ...
- Scrapy实战篇(八)之爬取教育部高校名单抓取和分析
本节我们以网址https://daxue.eol.cn/mingdan.shtml为初始链接,爬取教育部公布的正规高校名单. 思路: 1.首先以上面的地址开始链接,抓取到下面省份对应的链接. 2.在解 ...
- 32个Python爬虫实战项目,满足你的项目慌
爬虫项目名称及简介 一些项目名称涉及企业名词,小编用拼写代替 1.[WechatSogou]- weixin公众号爬虫.基于weixin公众号爬虫接口,可以扩展成其他搜索引擎的爬虫,返回结果是列表,每 ...
随机推荐
- ajaxGird修改一条记录中的字段
var rowData = ajaxgrid.getSelectedRow(); var quality = rowData["quality"]; var rowIndex = ...
- leetcode 198. House Robber 、 213. House Robber II 、337. House Robber III 、256. Paint House(lintcode 515) 、265. Paint House II(lintcode 516) 、276. Paint Fence(lintcode 514)
House Robber:不能相邻,求能获得的最大值 House Robber II:不能相邻且第一个和最后一个不能同时取,求能获得的最大值 House Robber III:二叉树下的不能相邻,求能 ...
- 配置Toad链接远程Oracle数据库
当前环境: 本机系统:Win7 64位 Toad版本:11 32位 数据库:Oracle 10g =================================== 与PLSQL Develope ...
- ABAP 实现内表自定义的F4功能
“实现多列内容的F4功能 REPORT Z_TAB_TEST. TYPES: shlp_descr TYPE shlp_descr . DATA: BEGIN OF itab OCCURS 0 ...
- java:JSP(JSPWeb.xml的配置,动态和静态导入JSP文件,重定项和请求转发,使用JSP实现数据库的增删改查实例)
1.JSP的配置: <%@ page language="java" import="java.util.*" pageEncoding="UT ...
- 使用 Unity* 进行并行处理的一种方法
本文展示如何使用 Unity* 对游戏进行并行处理,以及如何使用游戏引擎执行与游戏相关的物理.在这个领域内,现实感是成功的一个重要标志.为了模拟真实世界,许多动作需要同时发生,这需要并行处理.创建两个 ...
- python学习之socket&黏包
7.4 socket [重要] 避免学习各层的接口,以及协议的使用, socket已经封装好了所有的接口,直接使用这些接口或者方法即可,方便快捷,提升开发效率. socket在python中就是一 ...
- springboot笔记之helloworld
开发工具:IDEA 2019 springboot版本:2.1.9 一.springboot2.x VS 1.x 基础环境升级 最低 JDK 8,支持 JDK 9,不再支持 Java 6 和 7 依赖 ...
- 洛谷 P5043 树的同构 题解
题面 本题的难度其实不及紫题的难度.主要是在hash时的处理细节比较繁琐: 首先是树hash的模板: long long treehash(int u,int fa) { ]; ; ; for(int ...
- python-day18(正式学习)
目录 numpy模块 numpy简介 为什么要用numpy 创建numpy数组 numpy数组的基本属性 获取numpy数组的行列数 切割numpy数组 numpy数组元素替换 numpy数组的合并 ...