Python爬虫入门教程-2

1、Web请求全过程剖析... 1

2、浏览器工具的使用... 3

3、协议简单了解一下... 3

4、Requests模块入门... 4

5、获取豆瓣电影数据... 6

6、正则表达式... 7

7、实战1-爬取豆瓣top250电影... 9

8、实战2-爬取电影天堂热片... 11

9、HTML语法基础... 13

10、BS实战1-获取新发地菜价... 15

11、BS实战2-优化图库图片下载... 16

12、xpath解析... 18

13、xpath示例-猪八戒网址... 20

14、pyquery基础内容... 22

15、pyquery实战1-汽车之家购车信息... 24

16、requests进阶概述... 26

17、cookie-获取小说书架... 26

18、防盗链-下载梨视频... 28

9、HTML语法基础

Bs4解析比较简单,但是,首先需要了解一下基础的html只是,然后再去使用bs4去提取,逻辑和编写难度就会非常简单和清晰。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我是标题</title>
</head>
<body bgcolor="pink">
    <h1 align="right">我是中国人</h1>
    <p>刘德华是明星, 曾经是赌侠, 我特别佩服他。</p>
    <a href="www.baidu.com">刘德华的个人主页</a>
    <img src="abc.jpeg" width="60px" height="40px">
</body>
</html>
<!--
html基础语法:
  1、<标签名 属性=“值”>被标记的内容</标签名>
  2、<标签名 属性=“值” />
-->

BS基础练习

## 获取数据
# 安装bs4
# pip install bs4
from bs4 import BeautifulSoup
html = """
<ul>
    <li><a href="shixiaolong.com">释小龙</a></li>
    <li id="abc"><a href="wuqilong.com">吴奇隆</a></li>
    <li><a href="lixunhuan.com">李寻欢</a></li>
    <li><a href="leizhenzi.com">雷震子</a></li>
</ul>
"""
# 1、初始化BeautifulSoup对象
page = BeautifulSoup(html, "html.parser")
#page.find("标签名", attrs={"属性": "值"}) #查找某个元素,只会找到一个结果
#page.find_all("标签名", attrs={"属性": "值"}) #查找某个元素,只会找到一个结果
# li = page.find("li", attrs={"id": "abc"})
# a = li.find("a")
# print(a.text)  # 拿文本
# print(a.get("href"))  # 拿属性, get("属性名")
li_list = page.find_all("li")
for li in li_list:
    a = li.find("a")
    text = a.text
    href = a.get("href")
    print(text, href)

10、BS实战1-获取新发地菜价

新发地网页有变动,网页源代码上面不包含数据。不使用BS也能拿到数据。

不使用BS拿数据。

import requests
f = open("xfd.csv", mode="w", encoding='utf-8-sig')
url = "http://www.xinfadi.com.cn/getPriceData.html"
data1 = {
    "limit": "20",
    "current": "3"
}
resp = requests.post(url, params=data1)
# print(type(resp.json()))
dict = resp.json()
list_all = dict['list']
for li in list_all:
    # print(li)
    kind = li['prodCat']
    name = li['prodName']
    low = li['lowPrice']
    avg = li['avgPrice']
    high = li['highPrice']
    area = li['place']
    unit = li['unitInfo']
    datea = li['pubDate']
    # print(kind, name, low, avg, high, area, unit, datea)
    f.write(f"{kind},{name},{low},{avg},{high},{area},{unit},{datea}\n")
    # break
f.close()
resp.close()
print("北京新发地蔬菜第一页提取完毕.")

11、BS实战2-优化图库图片下载

网站有变化:https://www.umei.cc/bizhitupian/xiaoqingxinbizhi/

需求:下载图片

步骤:首页找到对应的href链接,子页面找到图片地址,然后下载下来。

下载源代码如下,

import requests
from bs4 import BeautifulSoup
domain = "https://www.umei.cc"
url = "https://www.umei.cc/bizhitupian/xiaoqingxinbizhi/"

resp = requests.get(url)
resp.encoding = "utf-8"
# print(resp.text)

n = 1
main_page = BeautifulSoup(resp.text, "html.parser")
a_list = main_page.find_all("div", attrs={"class": "item_b clearfix"}) # 过滤全部的包含a标签的div
for a in a_list:
    href_a = a.find_all("a")[0]["href"]  # 提取a标签
    # print(href_a)
    child_url = domain + href_a
    child_resp = requests.get(child_url)
    child_resp.encoding = "utf-8"
    # print(child_resp.text)
    # 子页面的bs对象
    child_bs = BeautifulSoup(child_resp.text, "html.parser")
    div1 = child_bs.find_all("div", attrs={"class": "big-pic"})
    img_src = div1[0].find_all("img")[0].get("src")
    # print(img_src)
    # 下载图片
    img_resp = requests.get(img_src)
    with open(f"pic/{n}.jpg", mode="wb") as f: #wb不止写文本,还可以写图片
        f.write(img_resp.content) # 把图片信息写入到文件中
    print(f"第{n}个图片下载完毕.")
    n += 1
View Code

数据存储在当前pic目录下。

12、xpath解析

理论知识过

知识点梳理,直接用代码演示。

from lxml import etree

xml = """
<book>
    <id>1</id>
    <name>野花遍地香</name>
    <price>1.23</price>
    <nick>臭豆腐</nick>
    <author>
        <nick id="10086">周大强</nick>
        <nick id="10010">谢大脚</nick>
        <nick class="joy">周杰伦</nick>
        <nick class="Jolin">蔡依林</nick>
        <div>
            <nick>哭了</nick>
        </div>
    </author>
    <partnet>
        <nick id="ppc">胖胖胖</nick>
        <nick id="ppbc">胖胖s胖</nick>
    </partnet>
</book>
"""
et = etree.XML(xml)
# result = et.xpath("/book")  # 表示根节点
# result = et.xpath("/book/name")  # 在xpath中间的/表示儿子
# result = et.xpath("/book/name/text()")[0]  # text()拿文本
# result = et.xpath("/book//nick")  # //表示所有的子孙后代
# result = et.xpath("/book/*/nick/text()") # /*/只拿表示孙子辈数据, *通配符,谁都行
# result = et.xpath("/book/author/nick[@class='joy']/text()")  # []表示属性筛选,@属性名=值
result = et.xpath("/book/partnet/nick/@id")  # 最后一个/表示拿到nick里面的id内容, @属性,可以直接拿到属性值
print(result)

html补充说明

htmla = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我是标题</title>
</head>
<body bgcolor="pink">
    <ul>
        <li><a href="http://www.baidu.com">百度</a></li>
        <li><a href="http://www.google.com">谷歌</a></li>
        <li><a href="http://www.sogou.com">搜狗</a></li>
    </ul>
    <ol>
        <li><a href="feiji">飞机</a></li>
        <li><a href="dapao">大炮</a></li>
        <li><a href="huoche">火车</a></li>
    </ol>
    <div class="job">李嘉诚</div>
    <div class="common">胡辣汤</div>
</body>
</html>
"""
et = etree.HTML(htmla)
# li_list = et.xpath("/html/body/ul/li/a/text()")
# li_list = et.xpath("/html/body/ul/li[1]/a/text()")  #数字表示第几个
li_list = et.xpath("//li")  # 全局查询li标签
# print(li_list)
for li in li_list:
    href = li.xpath("./a/@href")[0]  # ./表示当前节点
    text = li.xpath("./a/text()")[0]  # ./表示当前节点
    print(href, text)

13、xpath示例-猪八戒网址

需求:获取价格、名称和公司名称。

分析可以看到源代码,上面有需要的数据,直接拿 ,拷贝源代码到本地prcharm上面,

由于页面源代码较多,可以将源代码复制到pycharm上面,单独针对html文件提取数据。

源代码展示:

"""
# 拿到页面源代码
# 从页面源代码中提取你需要的数据,价格,名称,公司名称。
"""
import requests
from lxml import etree
url = "https://shenzhen.zbj.com/search/f/?type=new&kw=saas"
resp = requests.get(url)
resp.encoding = "utf-8"
# print(resp.text)

# 提取数据
et = etree.HTML(resp.text)
divs = et.xpath("//div[@class='service-card-wrap']/div")

for div in divs:
    # print(div)  # 此时的div就是一条数据,对应一个商品信息
    comany = div.xpath("./a/div[2]/div[1]/div/text()")
    price = div.xpath("./div[3]/div[1]/span/text()")
    name = div.xpath("./div[3]/div[2]/a/text()")
    # print(type(comany), len(comany))
    comany = comany[0] if(len(comany)==1) else exit()  # 这里是个疑问,源代码只能拿到前面6条数据。
    print(comany, price[0], name[0])
    # break

14、pyquery基础内容

理论知识过

from pyquery import PyQuery

html = """
<li><a href="http://www.baidu.com">百度</a></li>
"""
p = PyQuery(html)  # 加载html内容
# print(p)
# print(type(p))
# a = p("a")  # pyquery对象直接(css选择器)
# print(a, type(a))  # 依然是pyquery对象
# b = p("li")("a")  # 链式操作
# print(b.text())
# c = p("li a")
# print(c)

html1 = """
    <ul>
        <li class="aaa"><a href="http://www.baidu.com">百度</a></li>
        <li class="aaa" id="gg"><a href="http://www.google.com">谷歌</a></li>
        <li class="bbb"><a href="http://www.sogou.com">搜狗</a></li>
        <li class="bbb"><a href="http://www.test.com">测试</a></li>
    </ul>
"""
p1 = PyQuery(html1)
# a = p1(".aaa a")  # class="aaa"
# print(a)

# a = p1("#gg a")  # id="gg"
# print(a.attr("href"))  # 获取属性值
# print(a.text())  # 获取文本

# 来个坑操作:多个标签拿属性
# href = p1("li a").attr("href") # 多个标签拿属性,只能匹配到第一个
# print(href)
# its = p1("li a").items()
# for item in its:
#     href = item.attr("href") # 拿属性
#     text = item.text() # 拿文本
#     print(text, href)

"""
总结:
1、pyquery(选择器)
2、items()  当选择器选择的内容很多的时候,需要一个个处理的时候使用
3、attr("属性名")  获取属性信息
4、text()  获取文本
"""

# diva = """<div><span>热爱中国</span></div>"""
# pa = PyQuery(diva)
# html = pa("div").html()  # 全部需要
# text = pa("div").text()  # 只有文本,所有html标签不要
# print(html, text)

# pyquery对html结构修改
html2 = """
<html>
    <div class="aaa">哒哒哒</div>
    <div class="bbb">嘿嘿嘿</div>
</html>
"""
p2 = PyQuery(html2)
# p2("div.aaa").after("""<div class="ccc">达到撒多</div>""") #在XXX后面添加XXX标签
# p2("div.aaa").append("""<span">达到撒多</span>""")  # 插入XXX标签
# p2("div.bbb").attr("class", "aaa") # 修改XXX标签属性
p2("div.bbb").attr("id", "12308")# 新增XXX标签属性,有的话就是修改
p2("div.bbb").remove_attr("id")# 删除XXX标签属性
p2("div.bbb").remove()# 删除标签
print(p2)

15、pyquery实战1-汽车之家购车信息

思路,首看网页源代码,没有展示就F12看页面内容。

对方校验标签:F12->elements

链接地址有所变化:https://k.autohome.com.cn/146

地址:https://k.autohome.com.cn/146/index_6.html

 源代码展示,

"""
1. 提取页面源代码
2. 解析页面源代码, 提取数据
"""
import requests

# url = "https://k.autohome.com.cn/146/index_6.html"
url = "https://koubeiipv6.app.autohome.com.cn/pc/series/list?pm=3&seriesId=146&pageIndex=6&pageSize=20&yearid=0&ge=0&seriesSummaryKey=0&order=0"
# 1. 提取页面源代码
resp = requests.get(url)
dict_resp = resp.json()
# print(type(dict_resp))
dic_list = dict_resp['result']
# print(type(dic_list), dic_list)
list_a = dic_list["list"]
carname = "奥迪A8"
for lis in list_a:
    # print(lis)
    # carname = lis['carname'] if('carname' in lis) else carname = "奥迪A8"
    specname = lis['specname']  # carname+specname, 车型
    exinfolist = lis['exinfolist']
    scoreList = lis['scoreList']  # 依次是空间、驾驶感受、油耗...
    # print(scoreList[0]['value'], scoreList[1]['value'],scoreList[2]['value'],scoreList[3]['value'],scoreList[4]['value'],scoreList[5]['value'],scoreList[6]['value'],scoreList[7]['value'])
    distance = exinfolist[0]['value']  # 行驶里程
    actual_oil_consumption = exinfolist[1]['value']  # 百公里油耗
    buyprice = exinfolist[2]['value']  # 裸车购买价
    boughtDate = exinfolist[3]['value']  # 购买时间
    buyplace = exinfolist[4]['value']  # 购买地点
    # print(carname+' | '+specname)
    print(carname+' | '+specname,distance,actual_oil_consumption,buyprice,boughtDate,buyplace,
          scoreList[0]['value'], scoreList[1]['value'],scoreList[2]['value'],scoreList[3]['value'],scoreList[4]['value'],scoreList[5]['value'],scoreList[6]['value'],scoreList[7]['value'])
    # break

16、requests进阶概述

前期爬虫已经使用过headers,他是http协议中的请求头,一般存放一些和请求内容无关的数据,有时会存放一些安全验证信息,比如常见的user-agent、token、cookie等。

知识点:

模拟浏览器登录

防盗链处理->爬取梨视频数据

代理->防止被封IP

接入第三方代理

17、cookie-获取小说书架

Cookie示例:

注意:F12,看不到login信息,需要打开一些参数,参考链接:

https://www.cnblogs.com/Frank-guo/p/14004516.html

页面登录接口

代码展示:

# 登录 -> 得到cookie
# 带着cookie 去请求到书架url -> 书架上的内容

# 必须把上面的两个操作链接起来
# 可以使用session进行登录 ——》 session可以认为是一连串请求,整个过程cookie不会丢失

import requests
# 会话
session = requests.session()
data = {
    "loginName": "186XXX592",
    "password": "tt0123"
}
# 1.登录
url = "https://passport.17k.com/ck/user/login"
resp = session.post(url, data=data)
# print(resp.text)
# print(resp.cookies)

# 2.拿书架上的数据
resp1 = session.get("https://user.17k.com/ck/author/shelf?page=1&appKey=2406394919")
print(resp1.json())

"""
# 骚操作,直接在浏览器上登录,然后拷贝cookie到程序
url = "https://user.17k.com/ck/author/shelf?page=1&appKey=2406394919"
aaa = {
    "Cookie": "GUID=26e5778f-f657-45bc-900e-30d9fadebb5c; sa…"
}
resp = requests.get(url, headers=aaa )
print(resp.text)
"""
View Code

以上两种方法,骚操作比较快。

18、防盗链-下载梨视频

页面源代码查不到视频链接地址

第一次返回,并没有视频链接地址,拿就是通过其他手段或第二次请求获取的。

如上,二次请求的视频地址做了转换。

过程可能有点慢,耐心等待。

代码展示:

# https://www.pearvideo.com/video_1782921
# https://www.pearvideo.com/videoStatus.jsp?contId=1782921&mrd=0.5933374676366527
# https://video.pearvideo.com/mp4/short/20230525/1685075581758-15978930-hd.mp4
# https://video.pearvideo.com/mp4/short/20230525/cont-1782921-15978930-hd.mp4
"""
拿到contId
拿到videostatus返回的json ->srcURL
srcURL里面的内容进行修整
下载视频
"""
import requests
url = "https://www.pearvideo.com/video_1782921"
contId = url.split("_")[1]

videoStatusUrl = f"https://www.pearvideo.com/videoStatus.jsp?contId={contId}&mrd=0.5933374676366527"
# print(videoStatusUrl)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
    # 防盗链:溯源,当前本次请求的上一级是谁
    "Referer": url
}

resp = requests.get(videoStatusUrl, headers=headers)
# print(resp.text)
dic = resp.json()
srcUrl = dic["videoInfo"]["videos"]["srcUrl"]
systemTime = dic["systemTime"]
srcUrl = srcUrl.replace(systemTime, f"cont-{contId}")
# print(srcUrl)
# 下载视频
with open("a1.mp4", mode="wb") as  f:
    f.write(requests.get(srcUrl).content)
    print("下载完成")
View Code

如上,视频下载完成。

posted @ 2023-06-04 18:44  wang_wei123  阅读(46)  评论(0编辑  收藏  举报