前言

网页构成

首先介绍一个网页的基本构成:HTML负责网页的结构,CSS负责样式的美化,Javascript负责交互逻辑。

  • HTML
  • CSS
  • Javascript

点击 F12打开开发者工具(部分电脑可能为Fn + F12),使用元素选择工具,再将鼠标指针移动到任意网页元素,单击该元素则该元素对应的网页源代码会被选中。
从网页源代码中可看出,大部分网页元素是由诸如“\文本内容\”这样的源代码定义的,这些标识符称为HTML标签,它们有以下基本类型:

一些相关知识

网页的动态加载与静态加载

静态加载意为服务器一次性发送所有网页数据给终端,动态加载意为服务器发送的是一个网页模板,而后终端再通过Ajax或其他方式将数据(通常是JSON数据包)填入到模板中。有些网站能做到不刷新网页就能向服务器申请内容,比如b站的评论区,实际上数据是在点击了下一页后才申请下来的,这就是动态网页的典型应用。

正则表达式

正则表达式用于对字符串进行匹配操作,符合正则表达式的字符串能被匹配并提取出来。
基本类型:

  • 普通字符
  • 元字符

普通字符包含所有大写字母和小写字母、所有数字、所有标点符号、汉字和一些其他符号,元字符是指在正则表达式中具有特殊含义的专用字符,具体学习可参考菜鸟教程-正则表达式

XPath表达式

XPath表达式描述了从一个节点到另一个节点的路径,在python中,使用第三方模块lxml中的etree类可以将网页源代码实例化为一个etree对象,该对象可以视为一个树形结构,就像二叉树那样,通过XPath路径我们可以定位一个上级标签的任意下级标签。
在网页的开发者工具中,使用元素选择工具选定一个元素,在源代码处右击复制就可以得到它的XPath表达式。

Python库模块介绍

requests

简介

requests是pyhton的一个第三方模块,主要作用为模拟浏览器对服务器发起http或https协议的网络请求,从而获取网页的源代码,从而对数据进一步的分析。

函数介绍

get()

get()有3个参数,分别是:

1.headers
2.params
3.timeout
4.proxies

其中headers通过字典定义

获取数据

介绍使用requests获取数据的办法
1、获取网页的源代码

1
2
3
import requests as re
response = re.get(url='https://www.baidu.com')
print(response.text)

2、获取动态加载的数据
判断一个数据是通过静态加载还是动态加载,我们可以在源代码中搜素目标元素名字,如果存在,说明是提前写好的,是静态加载的;需要进一步确定则截获数据包,在其中搜素目标元素,存在则确定是动态加载的。
3、获取图片
在获取网页源代码的时候,我们调用了.text属性,因为网页源代码是文本,而图片文件应该使用.content属性来提取其二进制字节码。

爬取豆瓣Top250的电影名(分析Json数据包)

有兴趣的朋友可以一键复制代码运行试试。本代码需在环境中安装库requests、json,具体方法请自行百度,本文不赘述。
另外,如果打印出的状态码是443而不是200,需在请求头中添加cookie,具体方法在后文会讲解。

import requests
import json
url = 'https://movie.douban.com/j/chart/top_list'
params = {'type': '25', 'interval_id':'100:90', 'action': '', 'start':'0', 'limit': '166'}
headers = {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.67'
}
response = requests.get(url = url, params = params, headers = headers)
print(response.status_code)
content = response.json()
for i in content:
    print(json.dumps(i, indent = 4, ensure_ascii = False, separators = (', ', ': ')))
    break
with open('豆瓣电影动画排行榜.txt', 'w', encoding = 'utf-8-sig') as fp:
    for i in content:
        title = i['title']
        score = i['score']
        fp.write(title + '  ' + score + '\n')

Beautifulsoup

分析网页源代码最基础的方法是正则表达式,它是从字符串处理的角度来进行的

etree

同样是分析网页的源代码,我们可以选择实例化etree对象再对其分析,示例代码如下:

    import requests
    from lxml import etree
    import time

    headers = {
        'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.67',
    'cookie': 'douban-fav-remind=1; bid=SaNprzpZygI; ll="108307"; dbcl2="232690234:6n5Tkx8rlgI"; push_noty_num=0; push_doumail_num=0; ck=MLnJ; frodotk_db="59b1a87c8709e6b70d14f975951db425"'

    }

    def get_html(start):
        print('正在爬取',start)
        url = f'https://movie.douban.com/top250?start={start}&filter='
        reponse = requests.get(url=url,headers=headers)
        html = etree.HTML(reponse.text) # 网页字符串转换为element对象
        movie_lis = html.xpath("//ol/li")
        for li in movie_lis:
            title = ''.join(li.xpath("div/div[@class='info']/div[@class='hd']/a/span[1]/text()"))
            description = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/p/text()")).replace('\n', '').replace(
                ' ', ''
            )
            rating = ''.join(
                li.xpath("div/div[@class='info']/div[@class='bd']/div[@class='star']/span[@class='rating_num']/text()")
            )
            comment_num = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/div[@class='star']/span[4]/text()"))
            quote = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/p[@class='quote']/span/text()"))
            cover = ''.join(li.xpath("div/div[@class='pic']/a/img/@src"))
            save_data(title,description,rating,comment_num,quote,cover)

    def save_data(title,description,rating,comment_num,quote,cover) :
        with open('豆瓣TOP250.csv','a+',encoding='utf-8-sig') as f:
            movie_info = f'{title},{description},{rating},{comment_num},{quote},{cover}\n'
            f.write(movie_info)

    if __name__ == '__main__':
        with open('豆瓣TOP250.csv', 'a+', encoding='utf-8-sig') as f:
            head = '名称,简介,评分,评论人数,引言,封面图\n'
            f.write(head)
        for start in range(0,250,25):
            get_html(start)
            time.sleep(2) # 休眠2秒
        print('信息录入完成')

Selenium

requests只是模拟浏览器对网页服务器发起请求,而Selenium模块是直接控制浏览器,使用该模块需要安装浏览器驱动,且浏览器上方会出现“此浏览器正在被控制”的提示字样。


附录

Python环境介绍

Anaconda是一个管理Python环境和包的工具,Pycharm是一款强大的python集成开发环境(IDE)

Anaconda

Anaconda是一个环境管理工具,可很方便对python环境和包进行管理。
我们可以把这个软件理解为一个房子,不同的虚拟环境在其中就像是房间,是完全独立的,比如说我们在其中一个虚拟环境安装了pandas包,这个操作不会对其他虚拟环境产生任何影响,这就方便了我们管理项目import包,不至于打包一个环境把一堆杂七杂八的东西包括进去。

Anaconda常用指令

  1. conda info -e 列出虚拟环境
  2. 设置虚拟环境
    • conda creat —name 环境名字 python=3.8 : 创建一个虚拟环境
    • conda activate 环境名字 :激活一个虚拟环境,往后的指令都将在这个环境中进行
    • conda deactivate :退出当前的环境
  3. 操作虚拟环境
    • conda instal 包名
    • conda update 包名
    • conda remove 包名
    • cobda list 包名
    • conda info 包名
    • conda clean : 删除无用的缓存与临时文件

退出某个环境时,PS C:\Users\DIKLE>代表着你在根目录,此时命令行即为Windows的powershell,值得注意的是在任何时候你都可以执行conda create,不必次次退出,并不会发生环境嵌套的问题。

Pycharm

这是一款强大的python集成开发环境。
在解释器设置中可以添加Anaconda的虚拟环境,不必每次新建项目都新建虚拟环境,耗时长且占空间。