把setting中的机器人过滤设为False

ROBOTSTXT_OBEY = False

1 语法

artcile

选取所有子节点

/article

选取根元素 artile

article/a

选取所有属于artile的子元素中的a元素

//div

选取所有 div 元素(不管出现在文档任何位置)

article//div

选取所有属于artile元素的后代的 div 元素,不管出现在 article 之下的任何位置

//@class

选取所有名为 class 的属性。

/article/div[1]

选取属于article子元素的第一个div元素

/article/div[last()]

选取属于article子元素的最后一个div元素

/article/div[last()-1]

选取属于article子元素的倒数第二个div元素

//div[@lang]

选取所有拥有lang属性的div元素

//div[@lang='eng']

选取所有lang属性为eng的div元素

debug

1 pycharm

id是全局唯一的

re_selector2 = response.xpath('//*[@id="post-110595"]/div[1]/h1/text()')

如果class='entry-header'是全局唯一,可以比上面少一层节点。

re_selector3 = response.xpath("//div[@class='entry-header']/h1/text()")

2 scrapy shell

对某一页http://blog.jobbole.com/110595/ 进行debug

scrapy shell http://blog.jobbole.com/110595/

得到response对象。

可以用dir(response)看属性和方法。用type(response)看类型。

>>> title = response.xpath("//div[@class='entry-header']/h1/text()")
>>> title
[<Selector xpath="//div[@class='entry-header']/h1/text()" data='为什么该和程序员约会?我有 20 个理由'>]

如何获取title中的数据?使用extract()方法,得到数组,再用序号可以得到具体值。

>>> title.extract()
['为什么该和程序员约会?我有 20 个理由']
>>> title.extract()[0]
'为什么该和程序员约会?我有 20 个理由'

不直接extra()是因为title 可以保持为selector对象。

获取时间,把里面的文本用text()获取出来。再用strip()默认出去默认字符。

>>> create_date = response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0]
>>> create_date
'\r\n\r\n 2017/03/18 · '
>>> create_date = create_date.strip()
>>> create_date
'2017/03/18 ·'
>>> a = create_date.replace("·","").strip()
>>> a
'2017/03/18'
>>> b = create_date.strip("·")
>>> b
'2017/03/18 '
>>> b = create_date.strip("·").strip()
>>> b
'2017/03/18'

只取多个class属性中的一个,用xpath的函数 contains。

比如要选取span,但是class有多项。而只想要其中的vote-post-up,可以用xpath的contains。

<span data-post-id="" class=" btn-bluet-bigger href-style vote-post-up   register-user-only "><i class="fa  fa-thumbs-o-up"></i> <h10 id="110595votetotal">2</h10> 赞</span>
>>> response.xpath("//span[contains(@class, 'vote-post-up')]")
[<Selector xpath="//span[contains(@class, 'vote-post-up')]" data='<span data-post-id="110595" class=" btn-'>]

列表生成式

过滤评论

>>> response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()[0:]
['其他', ' 7 评论 ', '约会']
>>> [element for element in tag_list if not element.strip().endswith("评论")]
['其他', '约会']
tag_list = [ element for element in tag_list if not element.strip().endswith("评论") ]
tags = ",".join(tag_list)

以什么结尾一定是 .endswith()

extract_first()

对数组取第0个、第1个的时候,如果数组为空,则可能抛出异常。

但是如果用extract_first(),不用做异常处理,结果为空或者None。

def extract_first(self, default=None):
for x in self:
return x.extract()
else:
return default

类似于字典的get方法,提取不到就返回空。

最终 jobbole.py

# -*- coding: utf-8 -*-
import re
import scrapy class JobboleSpider(scrapy.Spider):
name = "jobbole"
allowed_domains = ["blog.jobbole.com"]
start_urls = ['http://blog.jobbole.com/110595/'] def parse(self, response):
# re_selector1 = response.xpath("/html/body/div[1]/div[3]/div[1]/div[1]/h1")
# re_selector2 = response.xpath('//*[@id="post-110595"]/div[1]/h1/text()')
# re_selector3 = response.xpath("//div[@class='entry-header']/h1/text()")
title = response.xpath("//div[@class='entry-header']/h1/text()").extract()[0]
create_date = response.xpath("//p[@class='entry-meta-hide-on-mobile']/text()").extract()[0].strip().replace("·","").strip()
praise_nums = response.xpath("//span[contains(@class, 'vote-post-up')]//h10/text()").extract()[0]
fav_nums = response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0]
match_re = re.match(".*?(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1)
comment_nums = response.xpath("//a[@href='#article-comment']/span/text()").extract()[0]
match_re = re.match(".*?(\d+).*", comment_nums)
if match_re:
comment_nums = match_re.group(1) content = response.xpath("//div[@class='entry']").extract()[0]
tag_list = response.xpath("//p[@class='entry-meta-hide-on-mobile']/a/text()").extract()
tag_list = [ element for element in tag_list if not element.strip().endswith("评论") ]
tags = ",".join(tag_list) # 通过css选择器提取字段
title = response.css(".entry-header h1::text").extract()[0]
create_date = response.css(".entry-meta-hide-on-mobile::text").extract()[0].strip().replace("·","").strip()
praise_nums = response.css("div.post-adds h10::text").extract()[0] # fav_nums = response.css("span[class*='bookmark-btn']::text").extract()[0]
fav_nums = response.css(".bookmark-btn::text").extract()[0]
match_re = re.match(".*?(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1) # comment_nums = response.css("span[class='btn-bluet-bigger href-style hide-on-480']::text").extract()[0]
comment_nums = response.css("a[href='#article-comment'] span::text").extract_first()
match_re = re.match(".*?(\d+).*", comment_nums)
if match_re:
comment_nums = match_re.group(1)
content = response.css(".entry").extract()[0]
tag_list = response.css("p.entry-meta-hide-on-mobile a::text").extract()
tag_list = [element for element in tag_list if not element.strip().endswith("评论")]
tags = ",".join(tag_list)
pass

最新文章

  1. Android组件化和插件化开发
  2. shiro重新赋值权限
  3. JAVA之Forward 和 Redirect的区别
  4. Linux运行等级,根目录,文件类型etc
  5. Scrum团队
  6. 关于JavaScript打印去掉页眉页脚
  7. golang thrift 总结一下网络上的一些坑
  8. java 命令行操作
  9. 为js和css文件自动添加版本号
  10. UIImagePickerController之Block回调
  11. 记一次Time-Wait导致的问题
  12. patch与diff的恩怨
  13. 用python演示一个简单的AST(抽象语法树)
  14. 在ASP.NET Core Web API中为RESTful服务增加对HAL的支持
  15. python爬虫(6)——正则表达式(三)
  16. 【SSH系列】Hibernate映射 -- 继承映射
  17. SQL优化(面试题)
  18. 使用 opendistro for elasticsearch 做为graylog的后端存储
  19. Debian中配置静态IP
  20. 《手机端》让多出的导航变水平拖动,不让他 float 撑下去

热门文章

  1. python开发基础教程
  2. XOR and Favorite Number Codeforces - 617E || [CQOI2018]异或序列
  3. AC自动机 HDOJ 2222 Keywords Search
  4. 字符串处理/贪心 Codeforces Round #307 (Div. 2) B. ZgukistringZ
  5. 191 Number of 1 Bits 位1的个数
  6. android开发学习——Mina框架
  7. jsp中提示修改成功
  8. asp.net网站接入QQ登录
  9. java获取公网ip以及物理地址和代理商
  10. Vue 学习之el、template、replace和vue的生命周期 参考网址:https://segmentfault.com/a/1190000008010666