评论([[comments.sum]])
提供
安装: scrapy, pywin32
使用:
在当前目录下生成 工程目录:
scrapy startproject projectName
在工程目录中使用命令 新创建一个爬虫文件:
scrapy genspider spiderName www.xxx.com
位置在 spiders 目录中执行工程,
scrapy crawl spiderName
![]()
在爬虫文件的 parse() 方法中,可以直接接受请求 url 的返回值,直接使用 xpath 进行行数据解析。
注意: xpath 方法返回的结果列表每一项为 selector 类型的对象, 获取元素的文本值需要
.extract() or .extract()
.extract()
就 xpath 方法返回的 selector 对象列表的文本值取出(也可接受单个 selector 对象),根据传入的对象返回 字符串 or 列表.extract_first()
获取列表第一个元素的文本值, 返回字符串基于终端指令
将 parse 方法的返回值储存到本地文件中。
scrapy crawl scrapy_test -o ./ret.json
(对数据格式要求严格,通用性差)
基于管道
items
# projectName/projectName/items.py
import scrapy
class ProjectnameItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
data = scrapy.Field()
content = scrapy.Field()
pipelines
# projectName/projectName/pipelines.py
from itemadapter import ItemAdapter
class ProjectnamePipeline:
fp = None
# 重写父类方法,该方法只在开始爬虫时被调用一次
def open_spider(self, spider):
self.fp = open('./res.json', 'w', encoding='utf-8')
self.fp.write('[')
def process_item(self, item, spider):
self.fp.write(str(item['data']) + ',')
return item
# 重写父类方法,该方法只在结束爬虫时被调用一次
def close_spider(self, spider):
self.fp.write(']')
self.fp.close()
print('over')
class UserPipeline:
def process_item(self, item, spider):
print('自定义管道类,:', item['data'].get('name'))
# 将 item 传递给下一个被执行的管道类
return item
settings.py 代码片段
# projectName/projectName/settings.py 代码片段
# UA 伪装
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 ' \
'Safari/537.36 '
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
# 配置日志级别
LOG_LEVEL = 'ERROR'
# 日志输出到文件
# LOG_FILE = 'scrapy.log'
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'projectName.pipelines.ProjectnamePipeline': 300,
'projectName.pipelines.UserPipeline': 301,
# 300 管道类执行优先级。数值越小优先级越高
}
spiders
# projectName/projectName/spiders/scrapy_test.py
import scrapy
from projectName.items import ProjectnameItem
"""
path:
需求:获取糗事百科的 文字发表者的 名字及段子
"""
class ScrapyTestSpider(scrapy.Spider):
# 爬虫文件的名称,类似于 flask路由的别名
name = 'scrapy_test'
# 允许的域名,start_urls列表中只有此域名及其子域名才会自动发送请求
# allowed_domains = ['www.xxx.com']
# 起始的url列表,该列表中存放的url,会被 scrapy自动进行请求的发送
start_urls = ['https://www.qiushibaike.com/text/']
# 用作数据解析:response为 start_urls每次访问成功 url的返会值 对象
def parse(self, response):
content_list = response.xpath('//*[@class="col1 old-style-col1"]/div')
data = []
for div in content_list:
# name = div.xpath('./div[1]/a[2]/h2/text()').extract_first()
name = div.xpath('./div[1]/a[2]/h2/text()')[0].extract()
content = div.xpath('.//div[@class="content"]/span//text()').extract()
temp = {
'name': name,
'content': ''.join(content)
}
data.append(data)
item = ProjectnameItem()
item['data'] = temp
yield item # 基于管道存储
return data
spiders
# xiaohua/xiaohua/spiders/img_name.py
import scrapy
"""
将网站下所有图片名称爬取下来
"""
class ImgNameSpider(scrapy.Spider):
name = 'img_name'
# allowed_domains = ['www.xi.com']
start_urls = ['http://www.521609.com/tuku/mxxz/']
# 生成一个通用的 url
page_url = 'http://www.521609.com/tuku/mxxz/index_%d.html'
num = 2
def parse(self, response):
lis = response.xpath('/html/body/div[4]/div[3]/ul/li/a/@title').extract()
if self.num < 29:
new_url = format(self.page_url % self.num)
self.num += 1
# 使用生成器完成多次请求的手动发送
yield scrapy.Request(new_url, callback=self.parse)
return lis
使用场景:如果解析的数据不再同一张页面中。深度爬取
spiders
# xiaohua/xiaohua/spiders/boos.py
import scrapy
from xiaohua.items import XiaohuaItem
# 对当前页面及其子页面进行爬取
class BoosSpider(scrapy.Spider):
name = 'boos'
allowed_domains = ['www.xxx.com']
start_urls = ['https://www.zhipin.com/c100010000-p150407/']
def parse_detail(self, response):
item = response.meta['item']
# 子页面爬取的数据
item['job_val'] = response.body
# 提交给管道
yield item
def parse(self, response):
lis = response.xpath('//div[@class="job-list"]//ul/li')
for li in lis:
job_name = li.xpath('.//span[@class="job-name"]/a/text() | .//div[@class="job-limit clearfix"]//text()') \
.extract()
url = '嗯,演示一下就行。0.0'
item = XiaohuaItem()
item['job_name'] = job_name
# 转到子页面进行爬取, 请求传参
yield scrapy.Request(url, callback=self.parse_detail, meta={'item': item})
# 分页爬取
# yield scrapy.Request(self.start_urls[0]+'?page=2', callback=self.parse)
相关推荐:
来自系列:Python 爬虫学习笔记评论([[comments.sum]])
[[item.name]] [[item.email]] [[item.date_time]]
[[itemSon.name]] [[itemSon.email]] [[itemSon.date_time]]
回复 @[[itemSon.reply_user.name]]:
加载更多([[item.son.length-2]])...