python爬虫之搜索简书文章

平时使用简书搜索内容的时候总感觉用着不怎么顺手,搜索出的内容乘次不齐,我自己比较倾向于去看点赞数量多的文章,这样的文章一般质量还可以,于是乎想用python来写一个用自己的规则来搜索内容的爬虫。

一、明确自己方向
打开简书网站,输入搜索内容搜索。右键检查元素(safari浏览器中),查看网页源码。一开始想,搜索出的文章标题和链接都在源码中,但是前前后后找了一下,没找到,问了两三个学过python的同学,他们也不清楚(我也是醉了0.0)。

1CA648E4-6DFB-47B0-A792-FEAD770F178F.png

在折腾了一下后自己打开抓包工具,看看搜索的时候会不会有与服务器的数据请求。果不其然,搜索的内容是通过http请求得到的。

63C52DC4-D6D5-4429-9424-05A6F82BB483.png

从上面的图片可以看出,返回的数据中包含了文章的标题,链接、作者、喜欢数量、搜索结果的总页数、搜索结果总数量,这些都是我想获取到,也是要用到的。

二、着手获取数据
然后自己构造一个http请求去获取数据。设置请求的链接、设置请求的header。这里我们是模拟浏览器来请求的,所以用到抓包获得的浏览器请求的时候的headers就可以了,全部复制下来,设置到请求的headers中。如果不是模拟浏览器来请求,请求会出错,获取不到内容,因为这是简书的反爬虫措施之一。

9C12AD91-A116-4EF1-9602-50BE880F5633.png

1.设置header:

headers = {
            # '(Request - Line)' : 'POST / search / do?q = ios & type = note & page = 1 & order_by = default HTTP / 1.1',
            'Host': 'www.jianshu.com',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:49.0) Gecko/20100101 Firefox/49.0',
            'Accept': 'application/json',
            'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
            'Accept-Encoding': 'gzip, deflate',
            'X-CSRF-Token': 'AaptezFCpyFRqRuLfUNSec2sXezPdSkevhSOumWdjmQBwcsqtFj7Y4++9C7q1KNYcdDeKYPYSx2LF8TOv/yraw==',
            'Referer': 'http://www.jianshu.com/search?q=ios&page=' + str(
                self.currentPageCount) + '&type=note',
            'Cookie': '_ga=GA1.2.1123264411.1477987596; _m7e_session=ca00c4a06553d05d9582f8608cec77d6; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2215f90ad001a20-0dec543cc50fda-485960-1024000-15f90ad001b249%22%2C%22%24device_id%22%3A%2215f90ad001a20-0dec543cc50fda-485960-1024000-15f90ad001b249%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%7D%7D; sajssdk_2015_cross_new_user=1; Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1509960778,1509981445; _gid=GA1.2.809709895.1509960780; signin_redirect=http%3A%2F%2Fwww.jianshu.com%2Fsearch%3Fq%3Dios%26page%3D1%26type%3Dnote; Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1509982101'
        }

2.设置请求的参数:


2EEFDCDB-392C-4143-B7D6-13A8F21D3080.png

这里我们看到有四个参数 q:搜索内容 type:搜索类型,这里我们就填note就可以了 page:页数 order_by:排序的顺序

因为返回的搜索是分页的,而我要遍历所有的分页去筛选内容,所以我要在设置请求的时候,要动态的去设置请求的页数。

 url = 'http://www.jianshu.com/search/do?q=' + 搜索内容 + '&type=note&page=' + str(
            页数) + '&order_by=default'

3.请求并解析数据


47B0B090-7EED-4D16-8C64-13CFB39BC3B2.png

通过观察返回的json数据,我们可以看到,搜索出的结果、总页数、每页的数据条数、搜索出的文章。

文章的总页数:total_pages
文章列表:entries
文章的数据结构:
标题:title
内容:content
有效url的一部分: slug (会在拼接文章链接的时候用到)
喜欢数:likes_count

匹配标题:

 dr = re.compile(r'<[^>]+>', re.S)
                airtcleTile = dr.sub('', airtcleTile)

4.请求错误处理:
当我们不断去请求的时候会报请求过于频繁的错误,这里我们需要等个一两秒再去请求。这样就能不断的请求数据了。

        elif (json_data.has_key('error')):
            print json_data['error']

            self.sleepCount += 1
            time.sleep(self.sleepCount)
            self.getUrl()

三、运行程序,静静等待获取的内容


运行程序结果
抓包数据

源码在这里,稍后我会继续增加功能。

#-*- coding: utf-8 -*-
import re
import urllib2
import json
import requests
import time

class JianShuSearch:

    def __init__(self):
        self.total_pages = 1
        self.userlink = []
        self.neadAirtcles = []
        self.currentPageCount = 1
        self.searchContent = ' '
        self.sleepCount = 2

    def getUrl(self):

        # while len(userlink) == 0:
        if (self.searchContent == ' '):
            self.searchContent = raw_input('请输入想检索的内容: ')

        url = 'https://www.jianshu.com/search/do?q=' + self.searchContent + '&type=note&page=' + str(
            self.currentPageCount) + '&order_by=default'
        headers = {
            # '(Request - Line)' : 'POST / search / do?q = ios & type = note & page = 1 & order_by = default HTTP / 1.1',
            'Host': 'www.jianshu.com',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:49.0) Gecko/20100101 Firefox/49.0',
            'Accept': 'application/json',
            'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
            'Accept-Encoding': 'gzip, deflate',
            'X-CSRF-Token': 'irU6/gcVeIjgX7alknOXf+jV5Ubi6FbsXlAB0cT5YWIyT4zbV7BNWg+180IAqX/DIQaDkVClfaB00M86dLfUNw==',
            'Referer': 'https://www.jianshu.com/search?q=ios&page=' + str(
                self.currentPageCount) + '&type=note',
            'Cookie': '_ga=GA1.2.1123264411.1477987596; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2215f90ad001a20-0dec543cc50fda-485960-1024000-15f90ad001b249%22%2C%22%24device_id%22%3A%2215f90ad001a20-0dec543cc50fda-485960-1024000-15f90ad001b249%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%7D%7D; Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1516764054; signin_redirect=https%3A%2F%2Fwww.jianshu.com%2Fsearch%3Futf8%3D%25E2%259C%2593%26q%3Dios; read_mode=day; default_font=font2; locale=zh-CN; _m7e_session=91e8f3ffb07619741a2be2821dde9f17; Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1516764082'
        }
        page = requests.post(url=url, headers=headers)  # 获取网页中的json文件。
        json_data = json.loads(page.text)
        if (self.currentPageCount == 1):
            self.total_pages = json_data['total_pages']

        if (self.total_pages > 0 and json_data.has_key('entries')):
            for airtcle in json_data['entries']:
                # 标题
                airtcleTile = airtcle['title']
                dr = re.compile(r'<[^>]+>', re.S)
                airtcleTile = dr.sub('', airtcleTile)
                # 链接
                slug = airtcle['slug']
                airtcleUrl = 'http://www.jianshu.com/p/' + slug

                likeCount = airtcle['likes_count']
                if (likeCount > 10):
                    self.neadAirtcles.append(airtcle)
                    titleAdnUrl = airtcleTile + ' ' + airtcleUrl + '  like: ' + str(likeCount)
                    print  titleAdnUrl
                    self.currentPageCount += 1
            if (self.currentPageCount < self.total_pages):
                time.sleep(self.sleepCount)
                self.getUrl()
        elif (json_data.has_key('error')):
            print json_data['error']

            self.sleepCount += 1
            time.sleep(self.sleepCount)
            self.getUrl()


jianshuSearch = JianShuSearch()
jianshuSearch.getUrl()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,027评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,773评论 25 709
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,825评论 1 92
  • 那首我和他都爱的歌 上完了一天班很累 下班和舍友逛了街逛了超市 拎着大包小包跌跌撞撞的回到了家 随手炒了两个明天带...
    漫长的白日梦w阅读 339评论 0 2
  • 你的名字 从你的全世界路过 申肖克的救赎 这个杀手不太冷 霸王别姬 东邪西毒 大话西游 大鱼海棠 人间世 我在故宫...
    Moewster阅读 391评论 0 0