简书博客列表爬取

最近在学习使用xpath解析网页!就尝试对简书的博客爬取!首先是单个用户的博客文章爬取!之后便继续尝试爬取简书网站中用户列表前100页的用户的文章!
首先是单个用户文章信息的爬取,主要信息包括:标题、文章链接、摘要、beta、阅读量、评论数、喜爱数、以及发布时间。
废话不多说,先上代码:

import requests
from lxml import etree
import os
#/html/body/div[1]/div/div[1]/div[1]/div[2]/ul/li[3]/div/a/p

def getResponse(url):
	#伪装浏览器
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0',
        'Connection': 'close'}
    try:
        r = requests.get(url, headers=header, timeout = 30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r
    except:
        return 0

def ResponseParse(r, alist):
    if r:
        dom = etree.HTML(r.text)
        bate_site = 'https://www.jianshu.com'
        # print(str(dom.xpath('/html/body/div[1]/div/div[1]/div[2]/ul/li[4]/div/div/span[3]/text()')))
        li_path = './/div[@id="list-container"]/ul/li'
        title_path = './/a[@class="title"]/text()'
        href_path = './/a/@href'
        abstract_path = './/div/p[@class="abstract"]/text()'
        beta_path = './/div/div/span[@class="jsd-meta"]/i[@class="iconfont ic-paid1"]'
        read_path = './/div/div/a/i[@class="iconfont ic-list-read"]'
        comment_path = './/div/div/a/i[@class="iconfont ic-list-comments"]'
        love_path = './/div/div/span/i[@class="iconfont ic-list-like"]'
        time_path = './/div/div/span[@class="time"]/@data-shared-at'
        lis = dom.xpath(li_path)

        for li in lis:
            article_lsit = []
            # print(etree.tostring(li, method='html', encoding='utf-8'))
            title = li.xpath(title_path)[0]
            href = li.xpath(href_path)[0]
            abstract = li.xpath(abstract_path)[0]
            link = bate_site + href
            if title:
                article_lsit.append(title)
                print("标题:" + str(title))
            else:
                article_lsit.append("无")
            if link:
                print("链接:" + link)
                article_lsit.append(link)
            else:
                article_lsit.append("None")
            if abstract:
                print("摘要:" + abstract.strip().replace("\n", ""))
                article_lsit.append(abstract.strip().replace("\n", ""))
            else:
                print("摘要:" + "无")
                article_lsit.append("无")
            betas_ = li.xpath(beta_path)

            if betas_:
                betas = betas_[0].xpath('../text()')
                print("beta:", str(betas[1]).strip().replace("\n", ""))
                article_lsit.append(str(betas[1]).strip().replace("\n", ""))
            else:
                print("beta:", 0)
                article_lsit.append("0")
            reads_ = li.xpath(read_path)
            if reads_:
                reads = reads_[0].xpath('../text()')
                print("阅读量:", str(reads[1]).strip().replace("\n", ""))
                article_lsit.append(str(reads[1]).strip().replace("\n", ""))
            else:
                print("阅读量:", 0)
                article_lsit.append("0")
            comments_ = li.xpath(comment_path)
            if comments_:
                comments = comments_[0].xpath('../text()')
                print("评论数:", str(comments[1]).strip().replace("\n", ""))
                article_lsit.append(str(comments[1]).strip().replace("\n", ""))
            else:
                print("评论数:", 0)
                article_lsit.append("0")
            likes_ = li.xpath(love_path)
            if likes_:
                likes = likes_[0].xpath('../text()')
                print("喜爱数:", str(likes[0]).strip().replace("\n", ""))
                article_lsit.append(str(likes[0]).strip().replace("\n", ""))
            else:
                print("喜爱数:", 0)
                article_lsit.append("0")
            time = li.xpath(time_path)
            print("发布时间:" + str(time)[2:-8])
            article_lsit.append(str(time)[2:-8])

            print('\n')
            alist.append(article_lsit)

        return len(lis)
    else:
        print("爬取失败!")

def Get_Total_Article(url):
    r = getResponse(url)
    dom = etree.HTML(r.text)
    article_num = int(dom.xpath('//div[@class="info"]//li[3]//p/text()')[0].strip())
    return article_num

def Get_author_name(url):
    #/html/body/div[1]/div/div[1]/div[1]/div[1]/a
    r = getResponse(url)
    dom = etree.HTML(r.text)
    author_name = dom.xpath('.//div[@class="main-top"]/div[@class="title"]/a[@class="name"]/text()')[0].strip()
    return author_name

def WriteTxt(alist, name):
    save_dir = '文章列表'
    save_dir = os.path.join(os.getcwd(), save_dir)
    if not os.path.exists(save_dir):
        os.mkdir(save_dir)
    save_name = os.path.join(save_dir, name)
    out = "标题:{0:{8}<10}\n链接:{1:{8}<10}\n摘要:{2:{8}<20}\nbeta:{3:{8}<10}\n阅读量:{4:{8}<10}\n评论数:{5:{8}<10}\n喜爱数:{6:{8}<10}\n发布时间:{7:{8}<10}\n"
    with open(save_name, 'w', encoding="utf-8") as f:
        for i in range(len(alist)):
            f.write(out.format(alist[i][0], alist[i][1], alist[i][2], alist[i][3], alist[i][4], alist[i][5], alist[i][6], alist[i][7], chr(12288)))
            f.write("\n")
        f.close()
    print("数据成功写入:"+save_name)

def main():  
	url = url_ + "?order_by=shared_at&page={}"
	print(url)
	author_name = Get_author_name(url.format(1))
	save_name = author_name + ".txt"
	article_total_count = Get_Total_Article(url.format(1))
	if article_total_count%9 == 0:
		spider_num = int(article_total_count/9)
	else:
		spider_num = int(article_total_count/9) + 1
	article_count = 0
	# print(article_total_count/9)
	artile_list = []
	for i in range(spider_num):
		spider_url = url.format(str(i + 1))
		r = getResponse(spider_url)
		article_count += ResponseParse(r, artile_list)

	WriteTxt(artile_list, save_name)
	print("作者:" + author_name + "共爬取了:" + str(article_count) + "篇文章!")

if __name__ == '__main__':
    main()

程序解释

接下来对程序中的几个重要方法进行解释。
getResponse(url)用于获取链接对应的响应,简书的反爬措施相对简单,只需要将headers伪装成浏览器即可。
程序的重头戏便是对获取的响应进行解析。该功能在ResponseParse(r, alist)中实现,其中参数alist用于存储文章信息。
https://www.jianshu.com/u/cbe095ae3d58为例,我们查看网页的源代码(f12)
在这里插入图片描述
在这里插入图片描述
我们可以清晰的看到在个人主页中所有的文章列表信息位于<li>标签中,于是我们写出<li>标签的xpath信息
li_path = './/div[@id="list-container"]/ul/li'
用于获取所有的<li>标签。进一步查看源代码,从而找到我们所需信息相对于<li>标签的相对路径。
在这里插入图片描述
根据观察到的源代码信息,能够写出所有所需信息的的xpath:

title_path = './/a[@class="title"]/text()'
href_path = './/a/@href'
abstract_path = './/div/p[@class="abstract"]/text()'
beta_path = './/div/div/span[@class="jsd-meta"]/i[@class="iconfont ic-paid1"]'
read_path = './/div/div/a/i[@class="iconfont ic-list-read"]'
comment_path = './/div/div/a/i[@class="iconfont ic-list-comments"]'
love_path = './/div/div/span/i[@class="iconfont ic-list-like"]'
time_path = './/div/div/span[@class="time"]/@data-shared-at'

值得注意的是,在写beta、阅读量、评论数、喜爱数的xpath路径时,一直写到了所需标签的下一级标签,这主要是因为在调试程序的时候发现有的文章有beta信息,有的确没有,而有的文章却有赞赏的信息。他们都位于<span>标签中,如果按顺序列举<span>标签就会出现错乱的情况。所以使用下一级标签来定位所需信息所在的标签。当我们需要当前信息时则使用“..”回退到上一级标签并获取其中包含的文本信息。
在获取发布时间时也遇到了问题,如果使用.//div/div/span[@class="time"]/text()'便无法获取其中的时间信息,所以只能想办法获取其data-shared-at属性值。
在解析文本时也对获取的数据进行了清洗,当获取的信息不存在时,则人为为其赋值。
本文的数据结构是将每一篇文章的信息构造一个列表,然后每获取一篇信息就将其增加到alist列表中。
当我们需要获取某一个标签或者元素的xpath路径时可以在源代码中选中改元素,然后右键再点击copy,选择copy xpath

在这里插入图片描述
另外每个人构造的xpath不一定相同,所以可以自己尝试按照自己的理解构造xpath
其实在对网页进行解析之后差不多完成了爬虫的功能,但是为了消除下拉加载对我们的爬虫造成的影响。进一步观察网页的url,发现https://www.jianshu.com/u/cbe095ae3d58?order_by=shared_at&page=1
链接中page的值能够控制网页的显示,而且每一个page对应9篇文章信息发现了这个规律,便可以计算出每一位作者需要爬虫爬取的url的次数。
因此需要获取作者文章的总数。于是有写了Get_Total_Article(url):方法,其实就是对网页进行解析,获得对应路径处的文本。
至此,爬虫便能循环爬取文章信息,直至将某一作者所有文章信息爬取完毕。
当我们想将爬取的信息保存到本地时,我们便需要在写一个保存数据的方法,为了唯一标识保存作者信息的文档,以作者主页的昵称命名文档,所以我们有写了Get_author_name(url)方法。
于是乎爬虫便能自动爬取简书中某一作者的所有文章信息。
效果如图:
在这里插入图片描述
之后在爬取某一作者的文章信息的基础上便尝试爬取简书网站大部分作者的文章信息边保存。简书全网爬取文章信息的介绍将在一篇博客中介绍。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
scrapy是一个用于网站抓和数据提的Python框架,而微博和简书分别是一个社交媒体平台和一个知识分享平台。要使用scrapy微博评论简书,可以按照以下步骤进行: 首先,需要安装好Python和scrapy框架。可以通过安装Python的pip包管理工具,并使用pip安装scrapy。 然后,对于微博,可以通过登录微博开放平台,注册一个开发者账号,并创建一个应用。获到应用的App Key和Secret Key,以便进行API调用。在scrapy项目的settings.py文件中添加好相应的key。 接下来,使用scrapy创建一个新的项目。可以使用命令行工具执行以下命令:scrapy startproject weibo 在项目的spiders目录下,创建一个新的spider。可以使用命令行工具执行以下命令:scrapy genspider weibo_spider "weibo.com" 编辑新创建的spider,编写微博评论的代码。可以使用weibo API提供的接口进行评论的。 然后,启动虫,执行以下命令:scrapy crawl weibo_spider 在简书的情况下,可以使用简书提供的API接口进行评论的抓。首先,需要注册一个账号,并通过简书的开发者平台获到相应的API Key。然后,使用获到的API Key进行API调用。 创建一个新的spider来实现对简书评论的,类似于上述微博的虫。 最后,启动虫,执行相应的命令来抓简书评论。 总之,使用scrapy微博评论简书可以通过利用它提供的网页抓和数据提功能,结合微博和简书的API进行相应的数据获。通过上述步骤的操作,可以简单实现这个目标。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Timer-419

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值