先将学习途径:【Python爬虫教程】花9888买的Python爬虫全套教程2023完整版现分享给大家!(已更新Scrapy项目)——附赠课程与资料_哔哩哔哩_bilibili

看到后面scrapy时又换了一家感觉原来的有点老->新的:

千锋Python基础scrapy爬虫框架超强教学_入门+实战+项目_小白速成必备_哔哩哔哩_bilibili

这些足够我写毕设和爬虫入门了,以下是笔记:

第一章:

# 爬虫: 通过编写程序来获取到互联网上的资源
# 百度
# 需求: 用程序模拟浏览器. 输入一个网址. 从该网址中获取到资源或者内容
# python搞定以上需求. 特别简单
from urllib.request import urlopen

url = "http://www.baidu.com"
resp = urlopen(url)

with open("mybaidu.html", mode="w") as f:
    f.write(resp.read().decode("utf-8"))  # 读取到网页的页面源代码
print("over!")
resp.close()  # 关掉resp

基本入门:读取网页源代码。

# 安装requests
# pip install requests
# 国内源
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests

import requests
query = input("输入一个你喜欢的明星")

url = f'https://www.sogou.com/web?query={query}'

dic = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}

resp = requests.get(url, headers=dic)  # 处理一个小小的反爬

print(resp)
print(resp.text)  # 拿到页面源代码
resp.close()  # 关掉resp

request入门

import requests

url = "https://fanyi.baidu.com/sug"

s = input("请输入你要翻译的英文单词")
dat = {
    "kw": s
}

# 发送post请求, 发送的数据必须放在字典中, 通过data参数进行传递
resp = requests.post(url, data=dat)
print(resp.json())  # 将服务器返回的内容直接处理成json()  => dict
resp.close()  # 关掉resp

response转换为json

import requests

url = "https://movie.douban.com/j/chart/top_list"

# 重新封装参数
param = {
    "type": "24",
    "interval_id": "100:90",
    "action": "",
    "start": 0,
    "limit": 20,
}

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}

resp = requests.get(url=url, params=param, headers=headers)

print(resp.json())
resp.close()  # 关掉resp

伪装自己为浏览器,记得request一定要close,不然连接无法释放

第二章:

import re

# # findall:  匹配字符串中所有的符合正则的内容
# lst = re.findall(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# print(lst)
#
# # finditer: 匹配字符串中所有的内容[返回的是迭代器], 从迭代器中拿到内容需要.group()
# it = re.finditer(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# for i in it:
#     print(i.group())

# # search, 找到一个结果就返回, 返回的结果是match对象. 拿数据需要.group()
# s = re.search(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# print(s.group())


# # match是从头开始匹配
# s = re.match(r"\d+", "10086, 我女朋友的电话是:10010")
# print(s.group())

# # 预加载正则表达式
# obj = re.compile(r"\d+")
#
# ret = obj.finditer("我的电话号是:10086, 我女朋友的电话是:10010")
# for it in ret:
#     print(it.group())
#
# ret = obj.findall("呵呵哒, 我就不信你不换我1000000000")
# print(ret)

s = """
<div class='jay'><span id='1'>郭麒麟</span></div>
<div class='jj'><span id='2'>宋铁</span></div>
<div class='jolin'><span id='3'>大聪明</span></div>
<div class='sylar'><span id='4'>范思哲</span></div>
<div class='tory'><span id='5'>胡说八道</span></div>
"""

# (?P<分组名字>正则) 可以单独从正则匹配的内容中进一步提取内容
obj = re.compile(r"<div class='.*?'><span id='(?P<id>\d+)'>(?P<wahaha>.*?)</span></div>", re.S)  # re.S: 让.能匹配换行符

result = obj.finditer(s)
for it in result:
    print(it.group("wahaha"))
    print(it.group("id"))

re入门,re(regex)正则表达式,匹配速度快,但是学习和写法有点反人类(相对另外几种)

# 拿到页面源代码.   requests
# 通过re来提取想要的有效信息  re
import requests
import re
import csv

url = "https://movie.douban.com/top250"
headers = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36"
}
resp = requests.get(url, headers=headers)
page_content = resp.text

# 解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)'
                 r'</span>.*?<p class="">.*?<br>(?P<year>.*?)&nbsp.*?<span '
                 r'class="rating_num" property="v:average">(?P<score>.*?)</span>.*?'
                 r'<span>(?P<num>.*?)人评价</span>', re.S)
# 开始匹配
result = obj.finditer(page_content)
# f = open("data.csv",mode="w",newline='',encoding="utf-8") 解决空一行问题
f = open("data.csv", mode="w")
csvwriter = csv.writer(f)
for it in result:
    # print(it.group("name"))
    # print(it.group("score"))
    # print(it.group("num"))
    # print(it.group("year").strip())
    dic = it.groupdict()
    dic['year'] = dic['year'].strip()
    csvwriter.writerow(dic.values())

f.close()
print("over!")
resp.close()  # 关掉resp

欢迎来到国际爬虫通用靶场[doge]--豆瓣top250

# 安装
# pip install bs4 -i 清华

# 1. 拿到页面源代码
# 2. 使用bs4进行解析. 拿到数据
import requests
from bs4 import BeautifulSoup
import csv

url = "http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml"
resp = requests.get(url)

f = open("菜价.csv", mode="w")
csvwriter = csv.writer(f)

# 解析数据
# 1. 把页面源代码交给BeautifulSoup进行处理, 生成bs对象
page = BeautifulSoup(resp.text, "html.parser")  # 指定html解析器
# 2. 从bs对象中查找数据
# find(标签, 属性=值)
# find_all(标签, 属性=值)
# table = page.find("table", class_="hq_table")  # class是python的关键字
table = page.find("table", attrs={"class": "hq_table"})  # 和上一行是一个意思. 此时可以避免class
# 拿到所有数据行
trs = table.find_all("tr")[1:]
for tr in trs:  # 每一行
    tds = tr.find_all("td")  # 拿到每行中的所有td
    name = tds[0].text  # .text 表示拿到被标签标记的内容
    low = tds[1].text  # .text 表示拿到被标签标记的内容
    avg = tds[2].text  # .text 表示拿到被标签标记的内容
    high = tds[3].text  # .text 表示拿到被标签标记的内容
    gui = tds[4].text  # .text 表示拿到被标签标记的内容
    kind = tds[5].text  # .text 表示拿到被标签标记的内容
    date = tds[6].text  # .text 表示拿到被标签标记的内容
    csvwriter.writerow([name, low, avg, high, gui, kind, date])

f.close()
print("over1!!!!")
resp.close()  # 关掉resp

bs4(beautiful soup 漂亮的汤),但我感觉还是selector更好用一点...

# xpath 是在XML文档中搜索内容的一门语言
# html是xml的一个子集
"""
<book>
    <id>1</id>
    <name>野花遍地香</name>
    <price>1.23</price>
    <author>
        <nick>周大强</nick>
        <nick>周芷若</nick>
    </author>
</book>
"""
# 安装lxml模块
# pip install lxml -i xxxxxx
# 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>热热热热热1</nick>
        </div>
        <span>
            <nick>热热热热热2</nick>
        </span>
    </author>

    <partner>
        <nick id="ppc">胖胖陈</nick>
        <nick id="ppbc">胖胖不陈</nick>
    </partner>
</book>
"""

tree = etree.XML(xml)
# result = tree.xpath("/book")  # /表示层级关系. 第一个/是根节点
# result = tree.xpath("/book/name")
# result = tree.xpath("/book/name/text()")  # text() 拿文本
# result = tree.xpath("/book/author//nick/text()")  # // 后代
# result = tree.xpath("/book/author/*/nick/text()")  # * 任意的节点. 通配符(会儿)
result = tree.xpath("/book//nick/text()")
print(result)

xpath入门:网页->找到要查找的元素->右键copy->copy xpath (不是copy full xpath)

在XPath(XML路径语言)中,copycopy full 是两个不同的操作,它们在复制节点时会有所不同。以下是它们的区别:

  1. copy:

    • copy 操作会复制当前节点及其所有子节点,但不会复制当前节点的属性。

    • 例如,如果你有一个节点 <node attr="value">content</node>,使用 copy 操作后,你会得到一个完全相同的节点,但属性不会被复制。

  2. copy full:

    • copy full 操作会复制当前节点及其所有子节点,并且也会复制当前节点的属性。

    • 例如,如果你有一个节点 <node attr="value">content</node>,使用 copy full 操作后,你会得到一个完全相同的节点,包括属性。

from lxml import etree


tree = etree.parse("b.html")
# result = tree.xpath('/html')
# result = tree.xpath("/html/body/ul/li/a/text()")
# result = tree.xpath("/html/body/ul/li[1]/a/text()")  # xpath的顺序是从1开始数的, []表示索引

# result = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()")  # [@xxx=xxx] 属性的筛选

# print(result)

# ol_li_list = tree.xpath("/html/body/ol/li")
#
# for li in ol_li_list:
#     # 从每一个li中提取到文字信息
#     result = li.xpath("./a/text()")  # 在li中继续去寻找. 相对查找
#     print(result)
#     result2 = li.xpath("./a/@href")  # 拿到属性值: @属性
#     print(result2)
#
# print(tree.xpath("/html/body/ul/li/a/@href"))

print(tree.xpath('/html/body/div[1]/text()'))
print(tree.xpath('/html/body/ol/li/a/text()'))
# 拿到页面源代码
# 提取和解析数据
import requests
from lxml import etree

url = "https://beijing.zbj.com/search/f/?type=new&kw=saas"
resp = requests.get(url)
# print(resp.text)

# 解析
html = etree.HTML(resp.text)

# 拿到每一个服务商的div
divs = html.xpath("/html/body/div[6]/div/div/div[2]/div[4]/div[1]/div")
for div in divs:  # 每一个服务商信息
    price = div.xpath("./div/div/a[1]/div[2]/div[1]/span[1]/text()")[0].strip("¥")
    title = "saas".join(div.xpath("./div/div/a[1]/div[2]/div[2]/p/text()"))
    com_name = div.xpath("./div/div/a[2]/div[1]/p/text()")[0]
    location = div.xpath("./div/div/a[2]/div[1]/div/span/text()")[0]
    print(com_name)

爬猪八戒网可惜这个网站已经改版了,代码仍然有参考意义