scrapy+jieba:从文字中了解它人内心

一.前述

因为最近在学习scrapy框架,而且框架涉及到的内容也比较多,所以就想着写一篇文章来巩固一下scrapy框架的知识。 那么问题来了,我应该爬什么东西呢?不巧想到了我同学在简书写了好多的文章(此处@不不不不不不热我的大佬同学),而且人的文章多数都是散文,像我这种理科男并且作文永远写不好的人,正好可以借鉴她的文章来做实例,间接性的引用人家的散文。

二.工具

  • scrapy (安装scrapy同时需要安装以下工具,可能Twisted用pip会安装不上去,https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted,这个网页里面会有twisted的下载地址)
    scrapy安装
  • jieba分词(把中文按词组的形式切割开,很好用的)
  • wordcloud(云图,生成一张词图)

三.详细解析代码

创建scrapy我们只需要在cmd中,scrapy startproject 文件名,这样就可以创建出以下文件了
此图来源网络

然后我们来具体了解以下各个文件的主要用途:

  • init.py 这个应该比较熟悉吧,项目的初始化文件。
  • items.py 定义我们爬取内容的相关属性
  • middlewares.py 中间件,用来处理爬虫的输入和请求输出(可以用来设置代理ip,还有response返回的值)
  • pipelines.py 这是一个独立的类,它接收到item的信息,并且做一些处理(像保存数据库,去重什么的)
  • setting.py 可以设置pipline或Spider的一系列组件
scrapy的结构图.png

我们还需要进入spider文件夹创建 scrapy genspider [文件名] [mydomain.com] spider文件


image.png

这个文件用来编写的可定制化的部分,负责解析response,产生items和url.(我们主要在这里写代码)
创建好之后会出现


image.png

四.观察网页

image.png

F12进入开发者工具,主要是想看一下网页时以什么形式加载的,现在大部分网页都会是动态加载的,所以我们要抓包看一下。
我现在访问的网页是:https://www.jianshu.com/u/1964293091a3
image.png

从图片中可以看到文章真正的网址确实不是浏览器访问的网址,当我下滑的时候还会出现更多的文章地址
image.png

所以我们请求的地址大致也明了了。开始写我们的spider。

五.代码

现在我们就要在spider里面写代码了
jianshutest.py
网页请求方法

from scrapy import  Request,Spider
import json


from simpleBook.items import JianshuItem

class JianshutestSpider(Spider):
    name = 'jianshutest'
    allowed_domains = ['www.jianshu.com']
    start_urls = ['http://www.jianshu.com/']
  
    def start_requests(self):
        #cookie:你登录的用户名和密码都会包含在cookie里面,登录之后就可以查到(见下图)
        cookies={'Cookie':'remember_user_token=W1syMzQ1MzA2XSwiJDJhJDEwJE9ZMzIubnpCb0lNNTljcUg2RnU3OWUiLCIxNTA5Nzc3NDI3LjUwNDk4ODciXQ%3D%3D--af364747dd6fde4d917738c0b0840d02da5a1298; _gat=1; _ga=GA1.2.958245445.1504323082; _gid=GA1.2.291615467.1509881668; Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1508066816,1508943110,1509777295,1509881668; Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1509886621; _m7e_session=11bbcabbcae48dd2cee207c683dcb867; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%222345306%22%2C%22%24device_id%22%3A%2215f5404a0055fc-03123bf21a3db8-e313761-2073600-15f5404a0069f0%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fwww.baidu.com%2Flink%22%2C%22%24latest_referrer_host%22%3A%22www.baidu.com%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%7D%2C%22first_id%22%3A%2215f5404a0055fc-03123bf21a3db8-e313761-2073600-15f5404a0069f0%22%7D'}
        #请求的url,注意因为网站是以json格式加载的,下滑网页会发现出现好多的XHR文件,page是不一样的,所以要遍历一下页数,我看了一下一共是17页,所以我们从1range到17
        url = 'http://www.jianshu.com/u/1964293091a3?order_by=shared_at&page={page}'
        for page in range(1,17):
            #现在不需要判断status了,直接用scrapy自带的Request方法就可以,(参数1:请求的url.参数2:做回调函数,也就是把返回的resoponse回调到第二个方法里.参数3:写入cookie)
            yield Request(url.format(page=page) , callback=self.first_parse,cookies=cookies)
cookie.png

图2.png

请求完网页后,我们要做处理了,定义第一次解析:

    def first_parse(self, response):
      #把请求头写到代码中,模拟浏览器
      headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                   '    Accept-Encoding': 'gzip, deflate, br',
                   '    Accept-Language': 'zh-CN,zh;q=0.9',
                   '    Cache-Control': 'max-age=0',
                   '    Connection': 'keep-alive',

                   '    Host': 'www.jianshu.com',
                   '    If-None-Match': 'W/"a2bf45c7e139d5c5890a6d1ad6946052"',
                   '    Upgrade-Insecure-Requests': '1',
                   '    User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'
                   }
      #因为是js的文件,所以要json.loads解析一下
      js = json.loads(response.text)
      for jsl in js.get('notes'):
          print(jsl)

打印一下,检查一下我们写的内容是否正确.


image.png

看图确实没有问题哈,我们可以看到网页中的包含的众多信息,有标题作者什么的,但是!并没有我们要的文章啊。从网页中我发现,每点击一个标题会进入到文章页面,所以我开始就觉得这里面应该会有每一篇文章对应的网址吧,可以现在看来并没有呀!于是我就点开文章页面观察了一下网址。


image.png

发现页面后面的尾数就是我们的slug呀,这样我把所有获取到slug加上前缀请求一下就可以了。
具体代码:
    def first_parse(self, response):
      headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                   '    Accept-Encoding': 'gzip, deflate, br',
                   '    Accept-Language': 'zh-CN,zh;q=0.9',
                   '    Cache-Control': 'max-age=0',
                   '    Connection': 'keep-alive',

                   '    Host': 'www.jianshu.com',
                   '    If-None-Match': 'W/"a2bf45c7e139d5c5890a6d1ad6946052"',
                   '    Upgrade-Insecure-Requests': '1',
                   '    User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'
                   }
      js = json.loads(response.text)
      #因为json文件里有key值和value值,现在所有的网页信息都在note这个key值,所以要get一下
      for jsl in js.get('notes'):
          item = JianshuItem()
          #获取slug值
          if 'slug' in jsl:
              article = jsl.get('slug')
              #拼接网页
              article_url = 'https://www.jianshu.com/p/'+ article
              for fields in item.fields:
                if fields in jsl:
                  #这里可以打印出item里所对应的值
                   # item[fields] = jsl[fields]
                    #print(item)
                     #递归请求到文章页
                    yield Request(article_url,callback=self.second_parse,headers=headers)
                else:
                    pass
    def second_parse(self,response):
        #请求到文章页,用css选择器把文章选出来,然后输出
        article_title =response.css('.note .post .article .title::text').extract_first()
        article_content = response.css('.note .post .article .show-content p::text').extract()
        item = JianshuItem()
        item['article_title'] = article_title
        item['article_content'] = article_content
        yield item
image.png

我们把这些文字写出到txt文本。需要在piplines写入这一段代码,或者用其他方法( ̄□ ̄||我当年是用xml解析出来的)

class TxtscrapyPipeline(object):
    def process_item(self, item, spider):
        # 获取当前工作目录
        base_dir = os.getcwd()
        fiename = base_dir + '/1.txt'
         # 从内存以追加的方式打开文件,并写入对应的数据
        with open(fiename, 'w') as f:
            f.write(str(item['article_content']))
            f.flush()
            return item

把符号什么的都要去掉,我们可以得到这样的一个txt文本

image.png

这样,我们就可以用jieba进行分词了,创建了jb.py(千万不要把文件名命名为jieba.py),不然导包时候会错误。
代码如下:

import jieba
from jieba.analyse import extract_tags
from wordcloud import WordCloud,ImageColorGenerator
import matplotlib.pyplot as plt
from os import path
#读取我们的txt文件
def open_file():
    with open('article.txt','r')as f:
        file_content = f.read()
        cut_content(file_content,200)
        show_picture(file_content)
        f.close()

def cut_content(file_content,max_words):
    #取txt文本里的关键词
    tags = extract_tags(file_content, topK=max_words)
    #定义为dict集合
    word_dict = dict()
    #jieba分词
    word_list = jieba.lcut(file_content)
    #遍历tags
    for tag in tags:
        #对tag计数
        freq = word_list.count(tag)
       #生成dict
        word_dict[tag] = freq
    for a in word_dict:
      #输出
        print(str(a) +':'+str(word_dict.get(a)))

生成结果.png

虽然有许多没用的词,但同时我们也看到了她内心一直要写出的词,(希望,父母,迷茫,孤独,签约。。。)
生成云图:

def show_picture(file_content):
    g = " ".join(jieba.cut(file_content))
    back_coloring = plt.imread(path.join("1487226734725.jpg"))  # 选取背景图片
    word_cloud = WordCloud(font_path='simsun.ttc',  # 设置字体
                           mask=back_coloring,  # 设置背景图片
                           background_color="white",  # 背景颜色
                           max_words=900,  # 词云显示的最大词数
                           max_font_size=50,  # 字体最大值
                           random_state=42)
    my_wordcloud = word_cloud.generate(g)  # 生成词云图
    plt.imshow(my_wordcloud)
    plt.axis("off")
    plt.show()
    word_cloud.to_file(path.join("jianshu.png"))  # 保存图片

def main():
    open_file()

if __name__ == '__main__':
    main()
Figure_1.png

六.结尾

首先特别感谢我的同学@不不不不不不热允许我拿她的文章来做实例,写这篇文章完全会透露一点她的隐私,但她还是接受了。当然,从最后的结果我们也可以看出她确实是一个努力上进,并且还有点悲观的女孩。
这篇文章主要是自己用来学scrapy框架写出来的,写了一段时间,主要原因还是自己喜欢学这些东西,如果有喜欢的爬虫或者是其他计算机方面的爱好者也可以联系我哈~
好啦!感谢大家的阅读~

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

推荐阅读更多精彩内容