Python 爬虫实战,模拟登陆爬取数据

Python 爬虫实战,模拟登陆爬取数据

从0记录爬取某网站上的资源连接:

  • 模拟登陆
  • 爬取数据
  • 保存到本地

结果演示:

源网站展示:
Python 爬虫实战,模拟登陆爬取数据_第1张图片

爬到的本地文件展示:

Python 爬虫实战,模拟登陆爬取数据_第2张图片


环境准备:

python环境安装

安装requests库

使用以下命令安装requests库

#(如果使用的是anaconda 下虚拟环境里的python   请在虚拟环境里执行下边命令)
pip install requests

安装bs4库

使用以下命令安装requests库

#(如果使用的是anaconda 下虚拟环境里的python   请在虚拟环境里执行下边命令)
pip install bs4

小试牛刀

环境准备好之后,可以写一个简单的Demo来测试一下
以CSDN下手

import requests
from bs4 import BeautifulSoup

def get_html(url):
    sesson = requests.Session()
    start_html = sesson.get(url)  #使用requests来发送请求
    soup = BeautifulSoup(start_html.text, 'lxml')  #使用BS4框架来解析网页源码
    print(soup)

if __name__=='__main__':
    url = 'https://www.csdn.net/'
    get_html(url)

正常输出网页代码:略

模拟登陆:

一般上边的代码获取网页源码之后就可以爬去自己想要的内容了,但是某些网站需要登陆之后才能获取想要爬去的内容。Python模拟登陆网站的方式有很多种,这里只介绍一种简单的使用网站cookie的方法:

  1. 首先,在浏览器端登录账号,用然后用网页工具获取登陆之后的cookie,以Chrome浏览器为例:在登陆界面按F2,点击Network,然后输入账号密码进行登陆

Python 爬虫实战,模拟登陆爬取数据_第3张图片

登陆之后,在name那一列找到含有cookies信息的文件点进去,然后在右边的Header里找到cookies和user-agent信息并保存下来。user-agent信息就是浏览器的信息,等会在写爬虫的时候要伪装成自己的浏览器,不然某些网站会有反爬虫机制,程序获取不了网页信息会报HTTP Error 403: Forbidden错误

Python 爬虫实战,模拟登陆爬取数据_第4张图片

  1. 在python中设置请求的头部,将爬虫伪装成浏览器,同时把cookies信息一起放到headers中。(小技巧:在pycharm中可以先敲一对引号,然后将cookies信息粘贴到引号中,这样可以省去调格式的时间;网站不需要登陆的把user-agent信息写到headers即可,避免发生HTTP Error 403: Forbidden错误)
    提示:实际上可以只用其中的某一段就可以实现登陆,我对cookies不太熟悉,所以选择了全部复制了过来,但是在使用的时候,有时候会不好使,我也不太清楚是为什么,在仔细观察cookies的内容是,发现有些参数对应多个值,把多余的删除之后就好使了
def get_html(url):
    headers = {

        'Cookie': 'only=a61236e8-cff4-40d7-98e5-cab9e6874859; .5118.referer={"TParam":"","QuestionParam":"","Referer":""}; .AspNet.ApplicationCookie=Rslw2TBMXcBLcyi9DG6RJQDgWLCZ7973g8KxyqK3seRjXMbQz8m1czehB75WXRWYSHzWwtUe_6QaRZ9tBp8h_asbnq2ctRnfUSl-L09fUOD6OCCEqo3kYLcj_-HiuaBT5mazCGMGG2gcpge2mBZGsAzbGIv57rAkfY0EQvYdX43VlPY4_DAPX-kNpA9y4ald3OeOINjyvzOMulX9LrUv726BHoup7Ql7Oyt03sMDS3RZGXEEBhiScoJDArVv-fiHfYB2wiA22q8gpLn-6MAZKpIYAl-XrdZdtcUdyHWFqKinU9TL46ZRNBWcbYoBrHjD4_VbNZ-5-SeoWTdw0QIIkLM-TJLn5UtGkhl5Sz63MRe1yuBuVokyjeaBwoFRFwG3soHsDjXHxXZ2VirvQK9TjBjvJwHhs5GR4-ODtJ_ZusN2c_BH4iFCQA2odzpejpA-IgoXeM5d4oO-eHekevGMvRfGEhd6rwjkiDITiSg9H38CVi-9J9g3IJlaYDDQzyTr8L9geewV8UOWUvPSWIr6yKQFEQ2qYJBuZw80xyohb54; ASP.NET_SessionId=n3yasgl3mumdnqkgypbanuxb; _5118_yx=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1Z3VpZCI6IjcyYjg0MGRkLWNjZmYtNGM1Ni1iOTkzLTZhNGNkYTg4ZjdjNiIsInVpZCI6OTkzMzY3LCJhdWQiOiJ3d3cuNTExOC5jb20iLCJpc3MiOiJ3d3cuNTExOC5jb20ifQ.diqxAy0k5GOmXjoVVQ9eFH-Hm6iKy97HfhIALa7dllM; Hm_lvt_f3b3086e3d9a7a0a65c711de523251a6=1606052087; Hm_lpvt_f3b3086e3d9a7a0a65c711de523251a6=1606130500',
        'User-Agent': 'Mozilla/5.0(Linux;Android6.0;Nexus5Build/MRA58N) AppleWebKit/537.36(KHTML, likeGecko) Chrome/87.0.4280.66MobileSafari/537.36'
    }  ###设置请求的头部,伪装成浏览器
    sesson = requests.Session()
    start_html = sesson.get(url,headers=headers)  #使用requests来发送请求
    soup = BeautifulSoup(start_html.text, 'lxml')  #使用BS4框架来解析网页源码
    return soup

爬取数据:

数据定位

在浏览器上按F2,点击开发者界面左上角的箭头,然后去页面上点击自己想要的数据,就会精确定位到页面元素在代码中的位置:

Python 爬虫实战,模拟登陆爬取数据_第5张图片
可以看到,想要的电影信息在两个a标签中,我们的目的是为了循环的获取页面所有的电影网站的信息,而每个电影信息都在dd标签中,所以应该找到其唯一的父标签,我们用class属性来判断其是否唯一。dd的父标签为dl,dl的class为dl-rank不唯一,所以继续向上找其父标签div,class为Fn-ui-list list,我们使用ctrl+f寻找Fn-ui-list list,发现标签唯一,所以我们要在这个div中循环获取电影的信息

Python 爬虫实战,模拟登陆爬取数据_第6张图片
获取唯一的标签,可以使用find,

# attrs 中是限制标签唯一的属性
div =  soup.find(name ='div', attrs={"class":"Fn-ui-list list"})

div中有多个dl,获取dl,必须使用find_all

# 获取的dl是一个 包含所有dl标签的列表
dl=  div.find_all('dl')

当找到目标标签的时候电影网址的时候可以使用 .string 来获取标签的内容, 使用 .get()来获取标签内部的属性的值:

在这里插入图片描述

# 获取a标签的内容  爱奇艺
movie_name =  a.string
# 获取a标签的href的值   XXXXXXX
movie_url = a.get('href')

有上边的方式之后,我们就可以使用循环来获取更多的信息了

def get_info(url):
    soup = get_html(url)
    movie_url = []
    movie_name = []
    div = soup.find(name='div', attrs={"class": "Fn-ui-list list"})
    l = 0  # 跳过第一个dl标签
    for i in div.find_all('dl'):
        l += 1
        if l == 1:
            continue
        # 获取dd标签
        dd = i.find(name='dd', attrs={"class": "col2-5 keyword"})

        # 获取span标签
        span = dd.find('span')

        # 获取所有a标签
        a = span.find_all('a')

        # 获取有电影网址的a标签
        link = span.find(name='a', attrs={"class": "url"})

        # 获取电影站的名字
        name = a[0].string

        # 从网页上获取的name中可能有特殊字符   在保存的时候会出错,  把特殊字符删除即可
        name = name.replace(u'\xa0', u'')
        name = name.replace(u'\u2006', u'')
        name = name.replace(u'\ue74b', u'')
        name = name.replace(u'\u200d', u'')

        # 保存到列表中
        movie_name.append(name)
        movie_url.append(link.string)
    return movie_url, movie_name

循环结束之后 就获取了该页面所有的电影网站信息

保存到本地

def save(movie_name, movie_url):

    #将电影站名和网址打包为一个列表
    movies = list(zip(movie_name,movie_url))

    #打开一个csv文件  没有的话自动创建   存在的话往里头追加数据
    f = open('E:/movies.csv', 'a+', encoding='GBK', newline='')

    # 2. 基于文件对象构建 csv写入对象
    csv_writer = csv.writer(f)

    # 3. 构建列表头
    csv_writer.writerow(["电影名", "地址"])

    # 4. 写入csv文件内容
    for row in movies:
        print(row)
        csv_writer.writerow(row)

    # 5. 关闭文件
    f.close()
    print("has saved!")

完整的代码

import requests
import csv
from bs4 import BeautifulSoup

def get_html(url):
    headers = {

        'Cookie': 'only=a61236e8-cff4-40d7-98e5-cab9e6874859; .5118.referer={"TParam":"","QuestionParam":"","Referer":""}; .AspNet.ApplicationCookie=Rslw2TBMXcBLcyi9DG6RJQDgWLCZ7973g8KxyqK3seRjXMbQz8m1czehB75WXRWYSHzWwtUe_6QaRZ9tBp8h_asbnq2ctRnfUSl-L09fUOD6OCCEqo3kYLcj_-HiuaBT5mazCGMGG2gcpge2mBZGsAzbGIv57rAkfY0EQvYdX43VlPY4_DAPX-kNpA9y4ald3OeOINjyvzOMulX9LrUv726BHoup7Ql7Oyt03sMDS3RZGXEEBhiScoJDArVv-fiHfYB2wiA22q8gpLn-6MAZKpIYAl-XrdZdtcUdyHWFqKinU9TL46ZRNBWcbYoBrHjD4_VbNZ-5-SeoWTdw0QIIkLM-TJLn5UtGkhl5Sz63MRe1yuBuVokyjeaBwoFRFwG3soHsDjXHxXZ2VirvQK9TjBjvJwHhs5GR4-ODtJ_ZusN2c_BH4iFCQA2odzpejpA-IgoXeM5d4oO-eHekevGMvRfGEhd6rwjkiDITiSg9H38CVi-9J9g3IJlaYDDQzyTr8L9geewV8UOWUvPSWIr6yKQFEQ2qYJBuZw80xyohb54; ASP.NET_SessionId=n3yasgl3mumdnqkgypbanuxb; _5118_yx=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1Z3VpZCI6IjcyYjg0MGRkLWNjZmYtNGM1Ni1iOTkzLTZhNGNkYTg4ZjdjNiIsInVpZCI6OTkzMzY3LCJhdWQiOiJ3d3cuNTExOC5jb20iLCJpc3MiOiJ3d3cuNTExOC5jb20ifQ.diqxAy0k5GOmXjoVVQ9eFH-Hm6iKy97HfhIALa7dllM; Hm_lvt_f3b3086e3d9a7a0a65c711de523251a6=1606052087; Hm_lpvt_f3b3086e3d9a7a0a65c711de523251a6=1606130500',
        'User-Agent': 'Mozilla/5.0(Linux;Android6.0;Nexus5Build/MRA58N) AppleWebKit/537.36(KHTML, likeGecko) Chrome/87.0.4280.66MobileSafari/537.36'
    }  ###设置请求的头部,伪装成浏览器
    sesson = requests.Session()
    start_html = sesson.get(url,headers=headers)  #使用requests来发送请求
    soup = BeautifulSoup(start_html.text, 'lxml')  #使用BS4框架来解析网页源码
    return soup


def get_info(url):
    soup = get_html(url)
    movie_url = []
    movie_name = []
    div = soup.find(name='div', attrs={"class": "Fn-ui-list list"})
    l = 0  # 跳过第一个dl标签
    for i in div.find_all('dl'):
        l += 1
        if l == 1:
            continue
        # 获取dd标签
        dd = i.find(name='dd', attrs={"class": "col2-5 keyword"})

        # 获取span标签
        span = dd.find('span')

        # 获取所有a标签
        a = span.find_all('a')

        # 获取有电影网址的a标签
        link = span.find(name='a', attrs={"class": "url"})

        # 获取电影站的名字
        name = a[0].string

        # 从网页上获取的name中可能有特殊字符   在保存的时候会出错,  把特殊字符删除即可
        name = name.replace(u'\xa0', u'')
        name = name.replace(u'\u2006', u'')
        name = name.replace(u'\ue74b', u'')
        name = name.replace(u'\u200d', u'')

        # 保存到列表中
        movie_name.append(name)
        movie_url.append(link.string)
    return movie_name, movie_url


def save(movie_name, movie_url):

    #将电影站名和网址打包为一个列表
    movies = list(zip(movie_name,movie_url))

    #打开一个csv文件  没有的话自动创建   存在的话往里头追加数据
    f = open('E:/movies.csv', 'a+', encoding='GBK', newline='')

    # 2. 基于文件对象构建 csv写入对象
    csv_writer = csv.writer(f)

    # 3. 构建列表头
    csv_writer.writerow(["电影名", "地址"])

    # 4. 写入csv文件内容
    for row in movies:
        print(row)
        csv_writer.writerow(row)

    # 5. 关闭文件
    f.close()
    print("has saved!")


if __name__=='__main__':
    url = 'xxxxxxxx'
    movie_name, movie_url = get_info(url)
    save(movie_name, movie_url)



你可能感兴趣的:(python学习,python,html,数据挖掘)