Scrapy框架入门-xpath

如果对xpath语法比较了解,可以只阅读总结部分

scrapy简介
异步和非阻塞的区别
异步和非阻塞的区别
scrapy爬虫的流程
流程
各模块的作用
模块的作用
入门
创建项目
scrapy startproject myspider

myspider是项目名

生成一个爬虫
scrapy genspider itcast "itcast.cn"

参数含义:itcast是爬虫名字,itcast.cn是爬取的范围,一般是域名
执行命令后,会在myspider/spiders生成itcast.py文件
myspider/spiders/itcast.py

import scrapy
class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    # 允许爬取范围
    allowed_domains = ['itcast.cn']
    # 最开始请求url地址
    start_urls = ['http://itcast.cn/']

    def parse(self, response):
        pass
提取数据

完善spider,使用xpath等办法

保存数据

pipeline中保存数据

启动爬虫
cd 项目根目录
scrapy crawl 爬虫名字
目录结构
|____myspider
| |____spiders
| | |______init__.py
| | |______pycache__
| | | |______init__.cpython-37.pyc
| | |____itcast.py
| |______init__.py
| |______pycache__
| | |____settings.cpython-37.pyc
| | |______init__.cpython-37.pyc
| |____middlewares.py
| |____settings.py
| |____items.py
| |____pipelines.py
|____scrapy.cfg

scrapy.cfg

[settings]
# 项目配置文件settings.py
default = myspider.settings

[deploy]
# 代码发布
#url = http://localhost:6800/
project = myspider

settings.py

  1. 设置日志级别
# 日志等级
LOG_LEVEL = "WARNING"

LOG_LEVEL = "WARNING"表示warning以下的错误不打印日志

xpath语法
基本语法
  1. 选取节点
路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素
//book 选取所有 book 子元素,而不管它们在文档中的位置
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置
//@lang 选取名为 lang 的所有属性,获得lang属性的值
  1. 谓语(Predicates)
    查找某个特定的节点或者包含某个指定的值的节点。谓语嵌在方括号中
路径表达式 结果
. 当前元素
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素
//title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00
/bookstore/book[price>35.00]//title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00
./book/following-sibling::price[1] 获取book节点的第一个price兄弟节点

注意:以下使用场景

<div class='a b'>test</div>

如果是用

xpath('//div[@class="a"]')

会取不到里面的值,可以用如下的表达式:

xpath('//div[contains(@class,"a")]')   #它会取得所有class包含a的元素

同时包含多个类的情况

xpath('//div[contains(@class,"a") and contains(@class,"b")]') #它会取class同时有a和b的元素

不要在任何选择器中出现tbody标签,可以阅读这篇文章https://hexfox.com/p/having-trouble-extracting-the-tbody-element-during-my-web-scrape/,了解为什么

Xpath选择器://table[@class="some_class"]/tbody/tr=> //table[@class="some_class"]/tr。

CSS选择器:table.some_class>tbody>tr=> table.some_class>tr

//这类只能在第一次选择时使用,以/开头表示从任意目录开始找

  1. 取值
表达式 示例 结果
text() /bookstore/book[1]/text() 选取属于 bookstore 子元素的第一个 book 元素,提取其文本
text() //bookstore/a[text()='abc'] 选取bookstrore子元素中文本为abc的a标签
extract() response.xpath("//div[@class='tea_con']//h3/text()").extract() 返回一个标签列表,不加extract()返回的是选择器
extract_first() item['title'] = li.xpath(".//h4/text()").extract_first() 返回一个标签,不加extract_first()返回的是选择器
@src //img/@src 返回所有图片的src
语法示例
  1. 路径选择 //
//div[@class='tea_con']//li

选取带有class属性,且值为tea_con的所有div元素下的所有li元素

  1. extract()
def parse(self, response):
    ret1 = response.xpath("//div[@class='tea_con']//h3/text()").extract()
    print(ret1)

extract()返回一个列表,里面是提取的元素

  1. extract_first()
def parse(self, response):
    li_list = response.xpath("//div[@class='tea_con']//li")
    for li in li_list:
        item = {}
        item['name'] = li.xpath(".//h3/text()").extract()[0]
        item['title'] = li.xpath(".//h4/text()").extract()[0]
        #item['title'] = li.xpath(".//h4/text()").extract_first()
        print(item)

extract()[0]表示选择符合条件的第一个元素,该方法如果数组为空会报错,而extract_first()在数组为空时会返回None,不会报错
使用场景
当只需要列表项中的数据的第一个结果时用extract_first()

完整案例
  1. 提取数据
    itcast.py
class ItcastSpider(scrapy.Spider):
    name = 'itcast'
    # 允许爬取范围
    allowed_domains = ['itcast.cn']
    # 最开始请求url地址
    start_urls = ['http://www.itcast.cn/channel/teacher.shtml']

# //表示从匹配的当前节点

    def parse(self, response):

        # ret1 = response.xpath("//div[@class='tea_con']//h3/text()").extract()
        # print(ret1)
        # scrapy返回的不是普通的列表,可以使用extract()提取列表中每项元素
        li_list = response.xpath("//div[@class='tea_con']//li")
        for li in li_list:
            item = {}
            item['name'] = li.xpath(".//h3/text()").extract_first()
            item['title'] = li.xpath(".//h4/text()").extract_first()
            yield item

最后yeild将提取的每一项交给pipiline处理

  1. 开启pipeline
    settings.py
ITEM_PIPELINES = {
   'myspider.pipelines.MyspiderPipeline': 300,
}

myspider.pipelines.MyspiderPipeline表示项目名.文件名.类名
300是优先级,数字越小,优先级越高

注意:

  1. 只有开启pipeline,才能在(pipelines.py)中对数据进行处理
  2. 优先级较高的pipeline必须把数据return回去,否则后面的pipeline不能接收到数据
总结
完善spider
parse

pipeline
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容