爬虫抓取网页数据(如何使用Scrapy通过Selector选择器从网页中提取出我们想要的内容)

优采云 发布时间: 2022-01-14 19:10

  爬虫抓取网页数据(如何使用Scrapy通过Selector选择器从网页中提取出我们想要的内容)

  本节内容

  在这个总结中,我将介绍如何使用 Scrapy 通过 Selector 选择器从网页中提取我们想要的内容,并将内容存储到本地文件中。

  我们的登陆页面是一个有七层楼的帖子。我们希望获得每个楼层的以下信息:

  选择器选择器

  在 Scrapy 中,BeautifulSoup 也可以用来解析网页,但是我们推荐使用 Scrapy 自带的 Selector 选择器来解析网页,没有别的原因,效率很高。Selector 选择器有两种选择方法,XPath 方法和 css 方法。我使用 XPath 方法。

  XPath

  XPath 是一种用于在 XML 文档中查找信息的语言。因为网上教程很多,这里推荐两个,我自己就不多说了。一个是菜鸟教程的XPath文字教程,另一个是极客学院的XPath视频教程。后者需要实名认证才能观看,不麻烦。我个人更喜欢后者,老师的解释很容易理解。相信我,按照教程看懂XPath只需要半个小时,再根据我下面的代码对比巩固一下,你就可以掌握了。

  使用 Chrome 分析网页

  我们使用Chrome浏览器(firefox类似)来分析网页,分析我们的XPath应该怎么写。例如,我们现在要分析帖子的标题

  右键单击帖子标题并选择检查

  

  此时Chrome的调试工具会跳出来,自动定位到源码中我们要检查的元素

  

  然后根据代码结构,我们可以很容易的得到它的XPath

  //*[@id="thread_subject"]/text()

  其实有时候可以直接右键元素,选择copy xpath,但是这种方法在实践中基本没用,因为很难找到多个网页的共同特征,所以总的来说还是要分析一下我们自己。

  

  这里需要提醒一个神坑,下面的代码也有体现。具体可以参考我之前写的这篇文章Scrapy匹配xpath时tbody标签的问题。

  这个坑的启示是,当你发现一个你觉得无法科学解释的错误时,检查你得到的源代码!

  代码

  废话不多说,直接上代码。

  首先,修改 items.py 文件以定义我们要提取的内容

  # -*- coding: utf-8 -*-

import scrapy

class HeartsongItem(scrapy.Item):

title = scrapy.Field() # 帖子的标题

url = scrapy.Field() # 帖子的网页链接

author = scrapy.Field() # 帖子的作者

post_time = scrapy.Field() # 发表时间

content = scrapy.Field() # 帖子的内容

  然后来到heartsong_spider.py,写爬虫

  # -*- coding: utf-8 -*-

# import scrapy # 可以写这句注释下面两句,不过下面要更好

from scrapy.spiders import Spider

from scrapy.selector import Selector

from heartsong.items import HeartsongItem # 此处如果报错是pyCharm的原因

class HeartsongSpider(Spider):

name = "heartsong"

allowed_domains = ["heartsong.top"] # 允许爬取的域名,非此域名的网页不会爬取

start_urls = [

"http://www.heartsong.top/forum.php?mod=viewthread&tid=8" # 起始url,此例只爬这个页面

]

def parse(self, response):

selector = Selector(response) # 创建选择器

table = selector.xpath('//*[starts-with(@id, "pid")]') # 取出所有的楼层

for each in table: # 对于每一个楼层执行下列操作

item = HeartsongItem() # 实例化一个Item对象

item['title'] = selector.xpath('//*[@id="thread_subject"]/text()').extract()[0]

item['author'] = \

each.xpath('tr[1]/td[@class="pls"]/div[@class="pls favatar"]/div[@class="pi"]/div[@class="authi"]/a/text()').extract()[0]

item['post_time'] = \

each.xpath('tr[1]/td[@class="plc"]/div[@class="pi"]').re(r'[0-9]+-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+')[0].decode("unicode_escape")

content_list = each.xpath('.//td[@class="t_f"]').xpath('string(.)').extract()

content = "".join(content_list) # 将list转化为string

item['url'] = response.url # 用这种方式获取网页的url

# 把内容中的换行符,空格等去掉

item['content'] = content.replace('\r\n', '').replace(' ', '').replace('\n', '')

yield item # 将创建并赋值好的Item对象传递到PipeLine当中进行处理

  最后,将爬取的数据保存在 pipelines.py 中:

  # -*- coding: utf-8 -*-

import heartsong.settings

class HeartsongPipeline(object):

def process_item(self, item, spider):

file = open("items.txt", "a") # 以追加的方式打开文件,不存在则创建

# 因为item中的数据是unicode编码的,为了在控制台中查看数据的有效性和保存,

# 将其编码改为utf-8

item_string = str(item).decode("unicode_escape").encode('utf-8')

file.write(item_string)

file.write('\n')

file.close()

print item_string #在控制台输出

return item # 会在控制台输出原item数据,可以选择不写

  跑

  还是进入项目目录,在终端输入

  scrapy crawl heartsong

  看看输出信息,没问题。

  

  看看生成的本地文件,也ok。

  

  

  概括

  这一部分介绍页面解析的方法,下一部分将介绍Scrapy爬取多个网页,这也是让我们的爬虫真正爬取的一部分。结合这两个部分,您将能够爬下我论坛上的所有帖子。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线