zoukankan      html  css  js  c++  java
  • 美丽汤的请求

    python3  requests + beautiful soup4

    去爬“豆瓣最受欢迎的影评”,目的是爬取这些影评的作者的个人资料

    1.模拟登陆

    豆瓣er知道,上豆瓣时,如果是未登录状态,访问几个页面后,豆瓣会跳转到一个登录页面请求你注册/登录。所以,小爬虫需要解决这个问题才能爬到终点。

    这里的解决方案就是模拟登陆。

    一种是先分析这个网站登录时要POST哪些数据,然后通过POST这些数据(如用户名、密码、验证码等)实现模拟登陆。

    还有一种是用自己实际登录后的cookie来模拟登陆。

    这里我用的是第二种方法,推荐新手用这个。够简单粗暴~

    那么怎么才能拿到小甜饼cookie呢?很简单:

    1)抓包获取cookie:

    我用的是chrome下的Fiddler应用(firefox下有httpfox)

    首先打开Fiddler,然后去登录豆瓣。登录完回到Fiddler,去找抓到的包。

    然后点击这条记录,拷贝我们的小甜饼cookie。

    好一条cookie!

    2)处理cookie

    这时我们拷贝而来的cookie是这种格式的bid=xxxxx;gr_user=xxxxxxx;__utma=xxxxx;…

    把它处理成字典就能使用啦。

    1 def cookie():
    2     raw_cookies = 'blah blah'
    3     cookies = {}
    4     for line in raw_cookies.split(';'):
    5         key, value = line.split('=', 1)
    6         cookies[key] = value
    7     return cookies

    3)模拟登陆

    给请求带上cookie就可以模拟登陆啦。(可以用只有登录才能查看的页面url来测试是否成功,比如自己看过的电影这个页面)

    1 import requests
    2 
    3 r = requests.get(url, cookies=cookies)

    2.分析页面元素

    通过观察页面元素,发现影评作者的个人主页地址就藏在<a class="author"></a>的href属性里。

    我们用beautiful soup来解析出作者个人主页的url。

    1 import requests
    2 from bs4 import BeautifulSoup
    3 
    4 r = requests.get("https://movie.douban.com/review/best/", cookies=cookies)
    5 page = r.content
    6 
    7 soup = BeautifulSoup(page, 'lxml')
    8 anchors = soup.select('a.author')
    9 url = a['href']

    是不是很简单呢?想爬取其他信息存储起来,方法也类似。可以看看beautiful soup的文档,很简单易懂。

    以及某些时候要用一些正则re,来匹配到需要的信息。比如要拿到粉丝的数量,rinka的个人主页显示xxx被666人关注。这里的“666”就要用正则拿到:

    1 import re
    2 
    3 el = soup.find("p", class_="rev-link").a  
    4 followers = re.findall(r'(d+)人关注$', el.getText())

     

    3.细节问题

    比如不设置间隔时间一直请求-美丽汤-请求-美丽汤的话,很可能会得到一个又一个的403页面。

    比如网站可能分页,需要观察url里的参数来循环请求-美丽汤。

    4.后续

    爬到的部分数据如下:

    {
    "昵称": "淮声",
    "常居地": "保密",
    "注册豆瓣时间": "2015/01/28",
    "粉丝": "30",
    "排名": 1
    },
    {
    "昵称": "凌睿",
    "常居地": "四川成都",
    "注册豆瓣时间": "2012/08/07",
    "粉丝": "4472",
    "排名": 2
    },
    {
    "昵称": "方城尉",
    "常居地": "保密",
    "注册豆瓣时间": "2016/12/10",
    "粉丝": "0",
    "排名": 3
    },
    {
    "昵称": "萌萌哒兔子",
    "常居地": "保密",
    "注册豆瓣时间": "2017/01/12",
    "粉丝": "10",
    "排名": 4
    },

    可以对数据做一些可视化分析等等。

    最后

    贴上完整代码:

    import requests
    from bs4 import BeautifulSoup
    import urllib.request
    import re
    import json
    import time
    from datetime import datetime
    
    
    def cookie():
        raw_cookies = 'blah blah'
        cookies = {}
        for line in raw_cookies.split(';'):
            key, value = line.split('=', 1) 
            cookies[key] = value
        return cookies
    
    
    def read_page(url, method="get"):
        '''
        read the html page via the URL
        '''
        status_code = 0
        headers = {"User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) 
                                 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36'}
        cookies = cookie()
        while status_code != 200:
            if method == "get":
                r = requests.get(url, cookies=cookies, headers=headers)
            elif method == "post":
                r = requests.post(url, cookies=cookies, headers=headers)
            status_code = r.status_code
            print(status_code)
        page = r.content
        return page
    
    
    def parse_person_profile(relative, info={}):
        '''
        retrieve the information from the personal profile page
        '''
    
        r = read_page(relative)
        soup = BeautifulSoup(r, 'lxml')
    
        # the living city of the author
        try:
            live = soup.find("div", class_="user-info").a.getText()
        except AttributeError:
            info['常居地'] = "保密"
        else:
            info['常居地'] = live
        print(info['常居地'])
    
        # author join douban since
        el = soup.find("div", class_="user-info")
        div = el.find("div", class_="pl")
        since = re.findall(r'(d+)-(d+)-(d+)加入$', div.getText())
        dt = datetime(year=int(since[0][0]), month=int(since[0][1]), day=int(since[0][2]))
        info['注册豆瓣时间'] = dt.strftime("%Y/%m/%d")
        print(div.getText(),info['注册豆瓣时间'])
    
        # the count of the followers
        el = soup.find("p", class_="rev-link").a
        followers = re.findall(r'(d+)人关注$', el.getText())
        print(followers)
        info['粉丝'] = followers[0]
    
        return info
    
    
    def douban_movie_popular_comment(page_url):
        '''
        workhouse
        '''
        r = read_page(page_url)
        soup = BeautifulSoup(r, 'lxml')
        global info
        anchors = soup.select('a.author')
    
        # get authors from list
        for index, a in enumerate(anchors):
            global i
            name = a.span.getText()
            print(name)
            p_info = {'昵称': name, '排名': i*10 + index + 1}
            m = a['href']
            time.sleep(3)  # 间隔几秒爬取一个作者,否则会由于反爬虫机制导致403
            parse_person_profile(m, p_info)
            info.append(p_info)
        return info
    
    if __name__ == "__main__":
        i = 0
        info = []
    
        while i < 5:
            num = i * 20  # 观察得出 URL序号按20增加
            url = 'https://movie.douban.com/review/best/?start=' + str(num)
            info = douban_movie_popular_comment(url)
            i += 1
    
        with open("movie", "w") as f:
            rlt = json.dumps(info, indent=4, ensure_ascii=False)
            f.write(rlt)
  • 相关阅读:
    如何设置IIS实现无扩展名重写
    正则表达式基础知识
    Literal控件用法
    ajaxPro.dll基础教程
    PetShop的系统架构设计
    SQL点滴29—错误无处不在
    javascript中的正则表达式
    为什么开发环境如此之乱
    SQL点滴文章总结
    javascript读写cookie
  • 原文地址:https://www.cnblogs.com/rinka/p/requests-beautifulsoup-douban-spider-using-cookie-to-login.html
Copyright © 2011-2022 走看看