查看原文
其他

【视频讲解】Scrapy递归抓取简书用户信息

2017-12-26

作者 大邓

https://v.qq.com/txp/iframe/player.html?vid=e0524pyrzv7&width=500&height=375&auto=0
https://v.qq.com/txp/iframe/player.html?vid=j05242y2g8s&width=500&height=375&auto=0

好久没有录制实战教程视频,大邓就在圣诞节后直接上干货。

之前写过一期【视频教程-用python批量抓取简书用户信息】的文章,是自己造的轮子,今天我趁着刚入门scrapy和xpath,操刀重写这个任务。

一、实战项目简介

递归

我们要大批量获取简书网站上的用户数据,最直接的办法是给一个初识的用户url,从这个用户的关注的和粉丝中再抽取url,循环往复,周而复始。这其实就是递归。

#注意我们一开始要研究的网址里是u,而不是user https://www.jianshu.com/u/811ae6268caa

数据项

获取到的url,我们需要对其进行请求,解析出想要的数据

 

  1. 昵称-nickname

  2. 关注数-followed

  3. 粉丝数- following

  4. 文章数-articles

  5. 文字数-charlength

  6. 喜欢数-likes


二、创建scrapy项目

2.1 创建项目

打开pycharm,点击左下角的terminal(mac上是这样,win应该类似)


scrapy startproject JianShu

2.2 生成爬虫

在terminal中我们要切换到项目文件夹中,在这里是JianShu文件夹,代码如下

cd JianShu

然后生成爬虫,注意爬虫名不能与项目名相同。

scrapy genspider 爬虫名 域名

scrapy genspider jianshu https://www.jianshu.com

三、构建爬虫各功能模块

scrapy爬虫框架,概括起来是

  1. spider下的爬虫脚本负责业务逻辑,发起请求,解析数据。

  2. middleware负责对爬虫进行伪装或者加代理

  3. item将爬虫脚本中的请求解析的数据封装到数据容器

  4. 并传递给pipeline以保存到csv、txt或者数据库中去。

  5. settings存储项目各种参数

  6. main主程序,运行开始爬数据

3.1 伪装请求头

一般为了让爬虫更健壮,我肯定不会跟网站说我是爬虫害虫,而是说我是好人,我来自浏览器人类的请求。

在scrapy中,我们先在settings.py中加入多个浏览器User-Agent,取消DOWNLOADER_MIDDLEWARES的前的注释。为了方便理解,我将里面的名字改成了HeadersMiddleware。

注意这里一定要DOWNLOADER_MIDDLEWARES字典中的value值写小一点,比如400。为了这个参数,我写好的没错的爬虫死活不运行,还总是403错误!!!!

DOWNLOADER_MIDDLEWARES = {    'jianshu.middlewares.HeadersMiddleware': 400}

UserAgentList = ["Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"]

然后在middleware.py中,定义我们的中间件。

from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
from jianshu.settings
import UserAgentList
import random

class HeadersMiddleware(UserAgentMiddleware):    """    给请求随机加入伪装头headers    """    def process_request(self, request, spider):        ua = random.choice(UserAgentList)        request.headers.setdefault('User-Agent:', ua)

3.2 item容器-整理数据

我们可以将item理解成存储数据的容器,类似于字典。只不过这个字典可以还有很多功能,可以在scrapy中飞来飞去的。挺神奇的。

from scrapy import Item,Field

class JianshuItem(Item):    nickname = Field()    description = Field()    followed = Field()    following = Field()    articles = Field()    charlength = Field()    likes = Field()

3.3 pipeline-存储到csv文件中

数据库我不太熟,直接用csv这种人见人会的方式保存数据吧。

经过item整理后的数据,我们就可以通过pipeline保存到csv中去。

首先打开pipelines.py文件

import csv

class CSVPipeline(object):        def __init__(self):

       self.csvf = open('data.csv', 'a+', encoding='gbk', newline='')
       self.writer = csv.writer(self.csvf)
       self.writer.writerow(('nickname', 'description', 'followed', 'fpllowing', 'articles', 'charlength', 'likes'))        
       self.csvf.close()            def process_item(self, item, spider):
       with open('data.csv', 'a+', encoding='gbk', newline='') as f:
           writer = csv.writer(f)
           writer.writerow((item['nickname'], item['description'], item['followed'], item['following'], item['articles'], item['charlength'], item['likes']))        
       return item

再打开settings.py,取消ITEM_PIPELINES注释。让item与pipeline完美衔接,一个负责整理数据,一个负责保存数据。

ITEM_PIPELINES = {    'JianShu.pipelines.CSVPipeline': 300,}

四、编写爬虫

前面的所有工作都是准备工作,我个人喜欢先做前面,做好后再编写爬虫。看个人喜好,其实你们如果愿意,也可以先写爬虫再写item、pipeline、middleware、settings。

4.1 解析数据

这里我们用到xpath解析,上一期的公众号文章已经分享,就不做仔细介绍了。大家不懂的就看看上一期文章。


注意,response.xpath()得到的是selector对象(而且是selector列表),selector对象有extract方法。所以

nickname = response.xpath("//div[@class='main-top']/div[@class='title']/a/text()").extract()[0]

#返回li的selector对象列表

info_selectors = response.xpath("//div[@class='main-top']/div[@class='info']/ul/li")        
followed_url = 'https://www.jianshu.com'+info_selectors[0].xpath("./div/a/@href").extract()[0]

followed = info_selectors[0].xpath("./div/a/p/text()").extract()[0]following = info_selectors[1].xpath("./div/a/p/text()").extract()[0]

articles = info_selectors[2].xpath("./div/a/p/text()").extract()[0]charlength = info_selectors[3].xpath("./div/p/text()").extract()[0]        
likes = info_selectors[4].xpath("./div/p/text()").extract()[0]        
description = re.sub('\s','',''.join(response.xpath("//div[@class='js-intro']/text()").extract()))          

补充。

#将string字符串中的pattern1替换成pattern2
re.sub(pattern1,pattern2,string)

4.2 关注列表解析

上面的解析都是一个人的关注、粉丝、文章数等信息的提取。其实我们为了递归批量获取简书用户信息,还需要大量的用户url。

而大量的用户url,最好的来源便是从关注与粉丝对应的用户列表中解析。

经过抓包发现


pages = int(float(followed)/10)

for page in range(1,pages+1):
   userlist_url = followed_url + '?page={page}'.format(page=page)    
   yield Request(userlist_url, callback=self.parseuserlist, dont_filter=True)


def parseuserlist(self,response):    
   url_list = response.xpath("//ul[@class='user-list']/li/div[@class='info']/a/@href").extract()    
   url_list = ['https://www.jianshu.com'+url for url in url_list]    
   yield Request(url,callback=self.parse,dont_filter=True)

整理汇总爬虫-jianshu.py

from scrapy import Spider, Request
from JianShu.items import JianshuItem
import re

class JianshuSpider(Spider):    name = 'jianshu'    allowed_domains = ['https://www.jianshu.com']    start_urls = ['https://www.jianshu.com/u/cf09bc3817a7']    def start_requests(self):        start_url = 'https://www.jianshu.com/u/811ae6268caa'        yield Request(start_url, callback=self.parse)            def parse(self, response):        item = JianshuItem()                nickname = response.xpath("//div[@class='main-top']/div[@class='title']/a/text()").extract()[0]        info_selectors = response.xpath("//div[@class='main-top']/div[@class='info']/ul/li")                followed_url = 'https://www.jianshu.com'+info_selectors[0].xpath("./div/a/@href").extract()[0]        followed = info_selectors[0].xpath("./div/a/p/text()").extract()[0]        pages = int(float(followed)/10)        for page in range(1,pages+1):            userlist_url = followed_url + '?page={page}'.format(page=page)            yield Request(userlist_url, callback=self.parseuserlist, dont_filter=True)                                        following_url = 'https://www.jianshu.com' + info_selectors[1].xpath("./div/a/@href").extract()[0]        following = info_selectors[1].xpath("./div/a/p/text()").extract()[0]                articles_url = 'https://www.jianshu.com' + info_selectors[2].xpath("./div/a/@href").extract()[0]        articles = info_selectors[2].xpath("./div/a/p/text()").extract()[0]        charlength = info_selectors[3].xpath("./div/p/text()").extract()[0]        likes = info_selectors[4].xpath("./div/p/text()").extract()[0]                description = re.sub('\s','',''.join(response.xpath("//div[@class='js-intro']/text()").extract()))                item['nickname'] = nickname        item['description'] = description        item['followed'] = followed        item['following'] = following        item['articles'] = articles        item['charlength'] = charlength        item['likes'] = likes                yield item  
         def parseuserlist(self,response):        url_list = response.xpath("//ul[@class='user-list']/li/div[@class='info']/a/@href").extract()        url_list = ['https://www.jianshu.com'+url for url in url_list]        for url in url_list:            yield Request(url,callback=self.parse,dont_filter=True)

五、开始爬爬爬

为了方便测试,后期运行,我们在项目跟目录定制了main.py文件 

5.1 main.py

直接在此更改,点击运行即可爬数据。

from scrapy.cmdline import execute
import os,sys sys.path.append(os.path.dirname(os.path.basename(__file__)))

#注意,jianshu是爬虫名,不是项目名

execute(['scrapy','crawl','jianshu'])

5.2 运行效果


5.3 代码下载地址

链接: https://pan.baidu.com/s/1o8kkF1K 密码: hmpj

支持大邓


数据采集

美团商家信息采集神器

使用gevent实现高效异步请求

selenium驱动器配置详解

爬虫神器PyQuery的使用方法

pyquery爬取豆瓣读书

pyquery一些自定义的用法

【视频】猫途鹰网站评论数据抓取

【视频讲解】在scrapy框架中如何使用selenium?

【实战视频】使用scrapy写爬虫-爬知乎live

简易SQLite3数据库学习

【视频教程】对视频进行基本操作

【视频】抓包小练习-B站评论数据抓取

fake-useragent库:值得花2分钟学习的库

【视频】爬取饿了么平台上的门店信息

如何抓取视频资源-以头条视频为例

当爬虫遭遇验证码,怎么办

【视频】手把手教你抓美女~

【视频】有了selenium,小白也可以自豪的说:“去TMD的抓包、cookie”

北邮人论坛爬虫实操:session代替cookies

【视频】快来get新技能--抓包+cookie,爬微博不再是梦

【视频教程】用python批量抓取简书用户信息

用Python抓取百度地图里的店名,地址和联系方式

文本处理分析

gensim:用Word2Vec进行文本分析

RAKE:快速自动抽取关键词算法

对于中文,nltk能做哪些事情

用nltk计算词语间的点互信息值PMI

用SenticNet库做细粒度情感分析

如何对csv文件中的文本数据进行分析处理

复杂网络分析数据准备篇

文本分析之网络关系

用词云图解读“于欢案”

基于共现发现人物关系的python实现

用pyecharts制作词云图

图片数据处理

OpenCV:快速入门图片人脸识别

好玩的OpenCV:图片操作的基本知识(1)

好玩的OpenCV:图像操作的基本知识(2)

OpenCV:计算图片有多色

如何对数据进行各种排序?

其他

迅雷不给力,我DIY了个下载器

【视频】初学者必看:python环境配置

开扒皮自己微信的秘密

初识装饰器函数

计算运行时间-装饰器实现

花十分钟,给爱机安装个MongoDB

chardet库:轻松识别文件的编码格式

使用Python登录QQ邮箱发送QQ邮件

WTF Python: 开启你的懵逼模式

8行代码实现微信聊天机器人

使用Python+OpenCV进行面部合成

十分钟学会用Flask发邮件


十分钟入门常用的json库


优雅简洁的列表推导式

【资源帖】简单易懂的机器学习视频教程


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存