Python 爬虫
什么是爬虫?
首先我们要了解,对于一个网站是有一个链接的。我们访问一个网站除了使用浏览器之外,还可以在 Linux 中使用 curl
命令访问
# 例如:访问百度
curl https://www.baidu.com/
会返回一个HTML的文件(网页的源码)
HTML -- 超文本编辑语言,专门用于前端
当然这个源码在网页中也能看到
也就是说,浏览器可以将源码解析成网页给我们看,而 Linux 的 shell 命令行不行
那么爬虫就是通过代码来访问 https://www.baidu.com
网页地址,爬取它的源数据,然后对其源数据进行解析,然后拿到我们想要的结果
当然源数据的格式可能有多种情况,有可能是 json 也可能是 html
如果源数据为 json 格式的,那么就会好解析一点
下面我们在微博手机版的网页中演示一下爬虫的使用
爬虫的使用
我们先进入浏览器的开发者工具,然后拿到微博评价数据的地址
然后通过使用爬虫的工具拉取数据并解析
requests
python 中爬虫的工具有很多
下面我们先看一个很基础的爬虫工具(requests)的使用
requests -- 需要先通过 pip 命令装一下
pip install requests
如何判断使用那种请求?
方式1:通过浏览器的地址栏可以直接访问的(可以直接拿到数据的) -- get请求,拿不到就用 post请求
方式2:
import requests
import json
# get请求:通过浏览器地址栏发起的请求,get请求的请求参数在url后面
# post请求:请求的参数在body(请求体)中, 一般用于登录上传用户名密码的时候
# 请求的路径(url)
# ?id=4750848993266460&mid=4750848993266460&max_id_type=0 -- ? 的后面都是参数
url = "https://m.weibo.cn/comments/hotflow?id=4750848993266460&mid=4750848993266460&max_id_type=0"
# 发起请求, 返回请求的结果
response = requests.get(url=url)
# 获取服务器响应请求后返回的结果数据
# 我们可以在IDEA中将拿到的json数据格式化之后看一下(通过IDEA将数据格式化)
text = response.text
print(text)
# 将返回的数据转换成json
json_loads = json.loads(text)
# 解析数据并将数据存起来
with open("com.txt", mode="w", encoding="utf-8") as f:
for data in json_loads["data"]["data"]:
# 评价的时间
created_at = data["created_at"]
# 评价的内容
text = data["text"]
# 点赞数
like_count = data["like_count"]
# 取出用户
user = data["user"]
user_id = user["id"]
screen_name = user["screen_name"]
gender = user["gender"]
line = "%s\t%s\t%s\t%s\t%s\t%s" % (user_id, screen_name, gender, like_count, created_at, text)
# 保存数据
f.write(line)
f.write("\n")
print(line)
json 格式好解析,就是那种网页格式的(使用浏览器地址栏访问地址直接显示网页的)就不是很好解析了
网页格式的就需要通过
xpath
来解析了,需要先通过 pip 安装pip install lxml
遇到带有反爬虫机制的网页,如果不加请求头,则程序跑完之后,什么数据都拉不到
那么如何找这个请求头呢?
还是一样的,要到浏览器的开发者工具中找
如何找
.xpath()
中需要的参数呢?要到浏览器的开发者工具中找
import requests
from lxml import etree
# 请求头
# 如果将上图中处理好的请求头中的全部内容放在这里,返回给我们的数据会乱码
# 所以我们只保留最后一个 User-Agent -- 误导网页服务端以为我们这个不是一个代码(爬虫),而是个浏览器
# 但是如果 User-Agent 不行的话,就需要将请求头中的全部内容一个一个的试一遍,直到找出返回正常数据的那个
# 有的时候需要 Cookie
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
}
# 请求页面获取网页数据
url = "https://movie.douban.com/top250?start=%7Bpage%7D&filter="
response = requests.request(url=url, method="get", headers=head)
# 获取响应的内容
text = response.text
# 解析html -- 使用 xpath
etree_html = etree.HTML(text)
# 获取所有影片
# .xpath() 中需要传入的参数上面说了怎么找
# // : 查询所有的(xpath的语法)
# ./ : 查询当前的(xpath的语法)
# [@class='hd'] -- @:表示引用变量,这里查询的是 class='grid_view' ,而不是上面图中所说的 class='hd'
# [@class='grid_view']/ -- 这里的 / 表示: class='grid_view' 里面(内层)的 li 标签
items = etree_html.xpath("//ol[@class='grid_view']/li")
# 遍历解析影片
# text() -- 拿到标签内的内容
# strip() -- 去掉字符串前后的空格或者制表符
for item in items:
# 一层一层的取出想要的数据,并打印
name = item.xpath("./div/div/div/a/span/text()")[0]
com = item.xpath("./div/div/div/div/span/text()")
score = com[0]
com_num = com[1]
dy = item.xpath("./div/div/div/p/text()")
dy1 = dy[0].strip()
year = dy[1].strip()
print(name, score, com_num, dy1, year)