一份系统化《Python爬虫教程》学习笔记:Python爬虫63个核心案例精讲(含反爬策略与源码剖析)

❤运行:ctrl+b

❤注释与取消注释:ctrl+/

❤将python打包成exe文件:

首先,在cmd中执行 pip install pyinstaller,安装 pip install pyinstaller

其次,在cmd中进入py文件所在路径,执行pyinstaller 你的py文件.py

1.爬取百度首页

py 复制代码
from urllib import request
url="http://www.baidu.com"
data=request.urlopen(url).read()
print(data)

2.爬取百度首页的标题

py 复制代码
from urllib import request
import re

url=r"http://www.baidu.com"
data=request.urlopen(url).read()    #获取的数据为bytes类型
#bytes类型:中文是以16进制码显示,需要用decode()进行解码
# print(data)
print(type(data))    #查看data的数据类型
data2=data.decode()    #decode解码,encode编码
#decode后的数据类型是str类型(字符串类型)
# print(data2)

pat=r"<title>(.*?)</title>"    #通过正则表达式进行数据清洗
str1=re.findall(pat,data2)
print(str1)

3.对抗网站反爬虫机制,伪装为浏览器的爬虫

py 复制代码
from urllib import request
import re

url=r"http://www.baidu.com"

#网站反爬虫机制1:判断用户是否是浏览器访问
#可以通过伪装成浏览器进行访问,对抗网站的反爬虫机制

#构造请求头信息:让字符串分多行显示
header={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Wi\
    n64; x64) AppleWebKit/537.36 (KHTML, like Ge\
    cko) Chrome/122.0.6261.95 Safari/537.36"
}
#让字符串分多行显示的办法:在每行的末尾加一个 \
#User-Agent的获取方法:1.在浏览器中按F12调出开发人员工具,在"网络"选项卡中点击一个对的链接,在"标头"中查找User-Agent
#2.百度搜索User-Agent,随意提取一个即可。

req=request.Request(url,headers=header)
data=request.urlopen(req).read().decode()

pat=r"<title>(.*?)</title>"
str1=re.findall(pat,data)
print(str1)

4.用多个User-Agent,伪装为不同浏览器,对抗网站反爬虫机制

py 复制代码
from urllib import request
import re
import random

url=r"http://www.baidu.com"
Agent1="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"
Agent2="Mozilla/5.0 (Linux; Android 7.1.1; OPPO R9sk) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.111 Mobile Safari/537.36"
Agent3="Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10"

list1=[Agent1,Agent2,Agent3]
Agent=random.choice(list1)
print(Agent)
header={"User-Agent":Agent}

req=request.Request(url,headers=header)
data=request.urlopen(req).read().decode()
print(data)

5.自定义opener

py 复制代码
from urllib import request
#同一个IP大量访问同一网站,ip可能会被屏蔽,这就需要使用代理ip

#构建HTTP处理器对象(专门处理HTTP请求的对象)
http_hander=request.HTTPHandler()

#创建自定义opener
opener=request.build_opener(http_hander)

#创建自定义请求对象
req=request.Request("http://www.baidu.com")

#发送请求,获取响应
data=opener.open(req).read().decode()

print(data)

6.设置自定义opener为全局

py 复制代码
from urllib import request

#构建HTTP处理器对象(专门处理HTTP请求的对象)
http_hander=request.HTTPHandler()

#创建自定义opener
opener=request.build_opener(http_hander)

#创建自定义请求对象
req=request.Request("http://www.baidu.com")

#把自定义opener设置为全局,这样用urlopen发送的请求也会使用自定义的opener
request.install_opener(opener)


#发送请求,获取响应
data=request.urlopen(req).read().decode()

print(data)

7.使用代理方式(不同IP)发送请求:

py 复制代码
from urllib import request
import random

#网站反爬虫机制2:判断请求来源的ip地址
#应对措施:使用代理ip
#免费代理ip查找办法:百度搜"代理ip",免费站点:https://www.89ip.cn/index_3.html
proxylist=[
{"http":"118.31.112.32:80"},
{"http":"113.223.214.91:8089"},
{"http":"112.17.16.250:80"}
]
proxy=random.choice(proxylist)

#构建代理处理器对象
proxyhandler=request.ProxyHandler(proxy)

#创建自定义opener
opener=request.build_opener(proxyhandler)

#创建请求对象
req=request.Request("http://www.baidu.com")
res=opener.open(req)

print(res.read())

8.处理get请求

py 复制代码
from urllib import request
import urllib
wd={"wd":"北京"}
url="http://www.baidu.com/s?"
#构造URL编码,将"北京"转化为地址中的显示的代码"%E5%8C%97%E4%BA%AC"
wdd=urllib.parse.urlencode(wd)
url=url+wdd

req=request.Request(url)
reponse=request.urlopen(req).read().decode()
print(reponse)

9.实战贴吧爬虫

py 复制代码
from urllib import request
import urllib
import time
header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}
# #url规律
# http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=0     (1-1)*50
# http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=50    (2-1)*50
# http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=100   (3-1)*50
# http://tieba.baidu.com/f?kw=python&ie=utf-8&pn=150   (4-1)*50
# for i in range(1,4):
#     print("http://tieba.baidu.com/f?kw=python&ie=utf-8&pn="+str((i-1)*50))
def loadpage(fullurl,filename):
    print("在正下载:",filename)
    req=request.Request(fullurl,headers=header)
    response=request.urlopen(req).read()    #此处不要decode,直接以二进制形式返回即可
    return response

def writepage(html,filename):
    print("在第保存:",filename)
    with open(filename,"wb") as f:    #wb表示以二进制形式打开
        f.write(html)

def teibaspider(url,begin,end):
    for page in range(begin,end+1):
        pn=(page-1)*50
        fullurl=url+"&pn="+str(pn)    #每次请求的完整url
        filename="d:/第"+str(page)+"页.html"        #每次请求后保存的文件名
        html=loadpage(fullurl,filename)        #调用爬虫,爬取见面
        writepage(html,filename)    #把爬取到的网页写入本地
        time.sleep(6)
        print("-------------------------------")

if __name__ == '__main__':
    kw=input("请输入贴吧名:")    #注由于有input,在sublime中无法执行
    begin=int(input("请输入起始页:"))
    end=int(input("请输入结束页:"))
    url="http://tieba.baidu.com/f?"
    key=urllib.parse.urlencode({"kw":kw})
    url=url+key

    teibaspider(url,begin,end)
    print("爬取完毕!")
    
#由由有input,在sublime中无法执行,需要将python的IDLE工具
#发送到桌面快捷方式,再将些py文件拖到IDLE快捷方式,再按F5执行

10.处理post请求

如果Request()方法里的data参数有值,那么这个请求就是post请求,否则就是get请求。

11.实战-有道翻译

py 复制代码
from urllib import request
import urllib

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}

#网址:http://m.youdao.com/translate
# url="http://m.youdao.com/translate"
#url="http://fanyi.baidu.com/mtpe-individual/multimodal"
url="http://fanyi.sogou.com/api/transpc/text/result"
#以上网站都没成功爬取

key="中国"

#需要提交的post数据
# formdata={    #有道的翻译
#     "inputtext":key,
#     "type":"AUTO",
# }
# formdata={        #百度的翻译
#     "domain": "common",
#     "from": "zh",
#     "needPhonetic":"true",
#     "query": key,
#     "to": "en"
# }
formdata={        #搜狗的翻译
    "client":"pc",
    "exchange":"false",
    "fr":"browser_pc",
    "from":"auto",
    "needQc":"1",
    "s":"7d472ca6863377bfec86011a9486bdd2",
    "text":key,
    "to":"en",
    "uuid":"73f17970-f61b-4535-948b-620f15bacaba"
}

data=urllib.parse.urlencode(formdata).encode(encoding='utf-8')

req=request.Request(url,data=data,headers=header)
response=request.urlopen(req).read().decode()
print(response)

12.异常处理

py 复制代码
from urllib import request

list1=[
    "http://www.baidu.com",
    "http://www.baidu.com",
    "http://www.fdfeddrrgdrrrhd.com",
    "http://www.baidu.com",
    "http://www.baidu.com"
]
i=0
for url in list1:
    i=i+1
    try:
        request.urlopen(url)
        print("第",i,"次请求完成!")
    except Exception as e:
        print(e)

13.cookie模拟登陆

py 复制代码
from urllib import request
url="https://iam.pt.ouchn.cn/am/UI/Login"

header={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36",
    "Cookie":"UUkey=0bb7f45c72f6be7ddb9cfd772f62b57c; eai-sess=AQIC5wM2LY4Sfczc4_3QfldAc8Lyydc4JaCTTrRqyez5Hy4%2AAAJTSQACMDEAAlNLABMtNTc0NTIxMDIxNzYzMzM1Njk0%2A"
}
req=request.Request(url,headers=header)
res=request.urlopen(req).read().decode()
print(res)

14.安装requests模块:在cmd中执行命令:pip install requests

py 复制代码
import requests
res=requests.get("http://www.baidu.com").content.decode()
print(res)

15.添加请求头和参数

py 复制代码
import requests
header={
     "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"
 }
wd={"wd":"中国"}
response=requests.get("http://www.baidu.com/s?",params=wd,headers=header)

data1=response.text        #返回字符串形式的数据
data2=response.content        #返回二进制形式的数据

print(data2.decode())

16.处理post请求

py 复制代码
import requests
import re

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}

url="http://fanyi.sogou.com/api/transpc/text/result"

key="中国"

formdata={        #搜狗的翻译
    "client":"pc",
    "exchange":"false",
    "fr":"browser_pc",
    "from":"auto",
    "needQc":"1",
    "s":"7d472ca6863377bfec86011a9486bdd2",
    "text":key,
    "to":"en",
    "uuid":"73f17970-f61b-4535-948b-620f15bacaba"
}
response=requests.post(url,headers=header,data=formdata)
print(response.text)
pat=r'"language":"(.*?)"'
result=re.findall(pat,response.text)
print(result[0])

17.代理ip

py 复制代码
import requests

proxy={
    "http":"http://42.63.65.107:80",
    "http":"http://49.7.11.187:80"
}
response=requests.get("http://www.baidu.com",proxies=proxy)

print(response.content.decode())
#免费代理ip查找办法:百度搜"代理ip",免费站点:https://www.89ip.cn/index_3.html

18.获取响应的cookie

py 复制代码
import requests

response=requests.get("http://www.baidu.com")

#获取返回的cooikejar对象
cookiejar=response.cookies
#将cooikejar转换成字典
cookiedict=requests.utils.dict_from_cookiejar(cookiejar)

print(cookiedict)

19.session实现登陆(以我要自学网为例)

py 复制代码
import requests

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}

#创建session对象
ses=requests.session()

#构造登陆需要的参数,以查看源代码方式寻找用户框和密码框的name名称为loginStr、pwd
data={"loginStr":"y****5","pwd":"5*****8"}

#通过传递用户名、密码得到cookie信息
ses.post("http://www.51zxw.net/login",data=data)


#请求需要的页面
response=ses.get("https://www.51zxw.net/Show.aspx?cid=732&id=79483")

print(response.text)

20.实战-爬取音乐资源(好听轻音乐网)

py 复制代码
import re
import requests
import time

#音乐列表网址
# http://www.htqyy.com/top/musicList/hot?pageIndex=0&pageSize=20
# http://www.htqyy.com/top/musicList/hot?pageIndex=1&pageSize=20
# http://www.htqyy.com/top/musicList/hot?pageIndex=2&pageSize=20


#单首音乐网址样式:
# http://www.htqyy.com/play/33
# <a href="/play/33" target="play" title="清晨" sid="33">清晨</a>

#单首音乐的资源网址:(进入单首音乐网址后,按F12,
# 在网络选项卡中,按下方向键一个个网址检查过去,查看其"标头"
# 的"请求网址")
#http://f5.htqyy.com/play9/33/mp3/8


songID=[]
songName=[]

for i in range(0,2):
    url="http://www.htqyy.com/top/musicList/hot?pageIndex="+str(i)+"&pageSize=20"

    #获取音乐榜单的音乐列表信息
    html=requests.get(url)
    strr=html.text

    pat1=r'title="(.*?)" sid='
    pat2=r'sid="(.*?)"'

    idlist=re.findall(pat2,strr)
    titlelist=re.findall(pat1,strr)

    songID.extend(idlist)    #把idlist加入到songID
    songName.extend(titlelist)


    for i in range(0,len(songID)):
        songurl="http://f5.htqyy.com/play9/"+str(songID[i])+"/mp3/8"
        songtitle=songName[i]
        data=requests.get(songurl).content
        print("正在下载第",i+1,"首")
        with open("d:/music/{}.mp3".format(songtitle),"wb") as f:
            f.write(data)

        time.sleep(5)

21.正则表达式介绍

py 复制代码
import re
strr="nicetomeetyou"
pat="meet"

rst=re.search(pat,strr)
print(rst)

22.体验-分析《天龙八部》主角到底是谁

py 复制代码
import re

with open("D:/python学习与笔记/tl.txt","rb") as f:
    data=f.read().decode()
pat1="乔峰"
pat2="萧峰"
pat3="段誉"
pat4="虚竹"

n1=re.findall(pat1,data)
n2=re.findall(pat2,data)
n3=re.findall(pat3,data)
n4=re.findall(pat4,data)

print("乔峰出现的次数:",len(n1)+len(n2),"段誉出现的次数:",len(n3),"虚竹出现的次数:",len(n4))

23.匹配变通字符

py 复制代码
import re

#原子:正则表达式中实现匹配的基本单位
#元字符:正则表达式中具有特殊含义的字符

#以普通字符作为原子(匹配一个普通字符)
a="湖南湖北广东广西"
pat="湖北"
result=re.search(pat,a)
print(result)

24.匹配通用字符

py 复制代码
import re
# \w 任意字母、数字、下划线
# \W 与小写w相反
# \d 十进制数字
# \D 除了十进制数以外的值
# \s 空白字符
# \S 非空白字符

b="13866648884000000000"
pat1=r"1\d\d\d\d\d\d\d\d\d\d"
print(re.search(pat1,b))

c="@@@###$$$%%%|||???!!%_dtdgdwww"
pat2=r"\W\w\w"
print(re.search(pat2,c))

25.匹配数字、中文、英文

py 复制代码
import re
#数字 [0-9]
#英文 [A-Z][a-z]
#中文 [\u4e00-\u9fa5]

d="!!!@@@##$$$张三%%%^^^&&&((boy))(##$%%^)@23@@@@@@@@@"
pat1=r"[\u4e00-\u9fa5][\u4e00-\u9fa5]"
pat2=r"[a-z][a-z][a-z]"
pat3=r"[0-9][0-9]"

result1=re.search(pat1,d)
result2=re.search(pat2,d)
result3=re.search(pat3,d)

print(result1,result2,result3)
    

26.原子表

py 复制代码
import re
#原子表:定义一组平等的原子
b="13866648884000000000"
pat1=r"1[35789]\d\d\d\d\d\d\d\d\d"    #以1开头,第2位是35789中的任意一个,后面再跟9个数
print(re.search(pat1,b))

c="虚竹段誉萧峰张无忌张三丰郭靖黄蓉"
pat2="[乔萧]峰"    #匹配乔峰和萧峰
print(re.search(pat2,c))

27.常用元字符

py 复制代码
import re

# 元字符:正则表达式中具有特殊含义的字符
# . 匹配任意字符(\n除外)
# ^ 匹配字符串开始位置,    ^136 表示以136开关
# $ 匹配字符串中结束位置, 66$ 表示以66结尾
# * 重复0次或多次前面的原子,\d*
# ? 重复一次或0次前面的原子,\d?
# + 重复1次或多次前面的原子,\d+

a="135895657891586523789513656238956"

pat1="..."
pat2=r"^135\d\d\d\d\d\d\d\d"
pat3=".*956$"
pat4="8*"
pat5="8?"
pat6="8+"

print(re.search(pat1,a))
print(re.search(pat2,a))
print(re.search(pat3,a))
print(re.search(pat4,a))
print(re.search(pat5,a))
print(re.search(pat6,a))

28.匹配固定次数

py 复制代码
import re
# {n} 前面的原子出现了n次
# {n,} 前面的原子出现了n次及以上
# {n,m} 前面的原子出现次数介于n-m之间

a="ade1234567890adeedgd"
pat1=r"\d{5}"
pat2=r"\d{8,10}"
pat3=r"\d{8,}"
pat4=r"\S{8,12}"    #表示任意非空字符出现8到12次
print(re.search(pat1,a))
print(re.search(pat2,a))
print(re.search(pat3,a))
print(re.search(pat4,a))

29.匹配多个正则表达式

py 复制代码
import re

# | 用于连接多个表达式

a="15880892443"
b="0598-6752866"
pat1=r"1[35789]\d{9}"    #以1开头,第2位是35789中的任意一个,后面再跟9个数
pat2=r"\d{3,4}-\d{7,8}"
pat3=r"1[35789]\d{9}|\d{3,4}-\d{7,8}"    #将a、b两个表达式合并
print(re.search(pat1,a))
print(re.search(pat2,b))
print(re.search(pat3,a))
print(re.search(pat3,b))

30.分组

py 复制代码
import re
# () 用于分组

a="dsfk12wej0ojlkdjavaddfdjfjd%@pythondaaa15880892443bbb!#@$"
pat=r"(java).{0,}(python).{0,}(1[35789]\d{9})"
pat2="aaa(.*?)bbb"    #表示匹配aaa和bbb之间的所有任意内容
print(re.search(pat,a))
print(re.search(pat,a).group(1))
print(re.search(pat,a).group(2))
print(re.search(pat,a).group(3))
print(re.findall(pat2,a))

31.贪婪模式和非贪婪模式

py 复制代码
import re
# 贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配
# 非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配(?),用?指定为非贪婪模式
# 在python里默念是贪婪模式

a="aa<div>test1</div>bb<div>test2</div>cc"

pat1="<div>.*</div>"    #贪婪模式
pat2="<div>.*?</div>"    #加一个?变成非贪婪模式
pat3="<div>(.*?)</div>"
print(re.findall(pat1,a))
print(re.findall(pat2,a))
print(re.findall(pat3,a))

32.compile函数

py 复制代码
import re

#compile函数---将正则表达式转换成python内部格式,提高执行效率
strr="Python888java"
pat=re.compile(r"\d+")
pat2=re.compile("PYTHON",re.I)    #re.I 模式修正符,忽略大小写
print(pat.findall(strr))
print(pat2.findall(strr))

33.match函数和search函数

py 复制代码
import re

# match函数--匹配开头
# search函数--匹配任意位置
#以上两个函数都只匹配一次就不再匹配了

strr="javapythonhtmljavajs"

pat=re.compile("(j)ava")
pat2=re.compile("python")

print(pat.match(strr).group())    #group()中不指定索引,则提取全部
print(pat.match(strr).group(1)) #group()指定索引,则提取索引对应的部分
print(pat2.search(strr).group())

34.findall函数和finditer函数

py 复制代码
import re

# findall() 查找所有匹配的内容,装到列表中
# finditer() 查找所有匹配的内容,装到迭代器中,无法直接打印,要用for一个个读取 

strr="hello--------------hello----------\
------------hello-------------hello------------\
----------hello--------------hello-----------"

pat=re.compile("hello")

data=pat.findall(strr)
data2=pat.finditer(strr)

for i in data:
    print(i)
print(data[0],data[1],data[2])

list1=[]
for i in data2:
    print(i.group())


data2=pat.finditer(strr)    #迭代器只能取一次,若要再次取,就要再装一次
for i in data2:
    list1.append(i.group())    #将i.group()装入列表list1中

print(list1)

35.split函数和sub函数

py 复制代码
import re
# split函数:返回按指定表达式分割的匹配字符串
# sub函数:用指定的字符串替换匹配到的字符串
str1="王刚,,小红,,,,陈八,,,,,,,赵东"
pat1=re.compile(",+")
res=pat1.split(str1)
print(res)

str2="hello 123,hello 456!"
pat2=re.compile(r"\d+")
res2=pat2.sub("666",str2)
print(res2)

36.实战-爬取网站电话号码(http://www.ip138.com/tel.htm)

py 复制代码
import re
import requests

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}
response=requests.get("http://www.ip138.com/tel.htm",headers=header)
data=response.content.decode()
# print(data)

#网站布局形式为:
# <td>诺基亚</td><td><b>4008800123 </b></td>
# <td>苹果</td><td><b>4006272273</b></td>

name=r"<td>(.*?)</td><td><b>.*?</b></td>"
tel=r"<td>.*?</td><td><b>(.*?)</b></td>"

pat1=re.compile(name)
pat2=re.compile(tel)

list1=[]
data1=pat1.findall(data)
data2=pat2.findall(data)

for i in range(0,len(data1)):
    list1.append(data1[i]+data2[i])
print(list1)

37.实战-爬取电影排名列表(豆瓣电影)

py 复制代码
import re
import requests

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}

url="https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action=&start=0&limit=20"

respone=requests.get(url,headers=header)
data=respone.content.decode()

#data中的是json数据,要匹配的数据格式如下:
# "rating":["9.7",
# "title":"肖申克的救赎"

rating=r'"rating":\["(.*?)",'        # \表示转义
title=r'"title":"(.*?)"'

pat1=re.compile(rating)
pat2=re.compile(title)

data1=pat1.findall(data)
data2=pat2.findall(data)

for i in range(0,len(data1)):
    print("排名"+str(i+1),":",data2[i],"--评分:",data1[i])

38.实战-爬取电视剧排名列表(豆瓣电影)

#中国大陆2024电视剧前20名排行版地址:

#https://m.douban.com/rexxar/api/v2/tv/recommend?refresh=0\&start=0\&count=20\&selected_categories={"地区":"中国大陆"}\&uncollect=false\&tags=中国大陆,2024

py 复制代码
import re
import requests

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}

url=r"http://m.douban.com/rexxar/api/v2/tv/recommend?refresh=0&start=0&count=20&selected_categories=%7B%22%E5%9C%B0%E5%8C%BA%22:%22%E4%B8%AD%E5%9B%BD%E5%A4%A7%E9%99%86%22%7D&uncollect=false&tags=%E4%B8%AD%E5%9B%BD%E5%A4%A7%E9%99%86,2024"

respone=requests.get(url,headers=header)
data=respone.content.decode()

print(data)
#本实验失败:url找不对?

39.xpath介绍和lxml安装

有同学说,我正则用的不好,处理html文档很累,有没有其他的方法?

有!那就是xpath,我们可以先将html文件转换成xml文档

然后用xpath查找xml节点或元素

需要安装lxml模块来支持xpath操作

使用pip安装:pip install lxml

40.解析字符串形式html

py 复制代码
from lxml import etree

text='''
 <div> 
     <ul> 
         <li class="item-0"><a href='link1.html'>张三</a></li>
         <li class="item-1"><a href='link2.html'>李四</a></li>
         <li class="item-inactive"><a href='link3.html'>王五</a></li>
         <li class="item-1"><a href='link4.html'>赵六</a></li>
         <li class="item-0"><a href='link5.html'>老七</a>
     </ul>
 </div>
 '''

#etree.HTML()将字符串解析成特殊的html对象(会自动补齐一些标签)
html=etree.HTML(text)

#将html对象转成字符串
result=etree.tostring(html,encoding="utf-8").decode()

print(result)

41.解析本地html文件

py 复制代码
from lxml import etree

#获取本地html文档
html=etree.parse(r"D:\python学习与笔记\left.html")
result=etree.tostring(html,encoding="utf-8").decode()

print(result)

42.获取一类标签

py 复制代码
from lxml import etree

html=etree.parse(r"D:\python学习与笔记\left.html")
res=html.xpath("//a")    #表示获取所有a标签的信息,返回的是列表类型数据

for i in range(0,len(res)):
    print(res[i].text)

43.获取指定属性的标签

py 复制代码
from lxml import etree

html=etree.parse(r"D:\python学习与笔记\left.html")
res=html.xpath("//li[@class='list-item2']")    #获取class名为list-item2的li标签中的信息
print(res[0].text)

res2=html.xpath("//li/a[@href='html/p1.html']")    #获取li标签下的href='html/p1.html'的a标签中的信息,
print(res2[0].text)

44.获取标签的属性

py 复制代码
from lxml import etree

html=etree.parse(r"D:\python学习与笔记\left.html")
res=html.xpath("//li/@class")    #获取li标签的class属性
for i in range(0,len(res)):
    print(res[i])

res2=html.xpath("//li/a/@href")    #获取li标签下的a标签中的href属性(即url地址)
for i in res2:
    print(i)

45.获取子属性

py 复制代码
from lxml import etree

html=etree.parse(r"D:\python学习与笔记\left.html")
res1=html.xpath("//li/a/span")    #获取li下的a下的span标签中的信息(一个斜杠:层层递进,两个斜杠:一网打尽)
print(res1[0].text)

res2=html.xpath("//li//span")    #获取li下的span标签中的信息,不论span是li的子标签,还是li的孙标签(孙标签表示子标签的子标签)(两个斜杠表示一网打尽)
for i in res2:
    print(i.text)

#获取li标签下的a标签里所有的class,不论其class是隶属于a还是隶属于a的子标签
res3=html.xpath("//li/a//@class")
for i in res3:
    print(i)

46.获取标签内容和标签名

py 复制代码
from lxml import etree

html=etree.parse(r"D:\python学习与笔记\left.html")

#获取倒数第二个li元素下a的内容,方法1:
res=html.xpath("//li[last()-1]/a")
print(res[0].text)

#获取倒数第二个li元素下a的内容,方法2:
res=html.xpath("//li/a")    #获取所有
print(res[-2].text)        #-2表示倒数第二个

#获取class为bold的标签名
res=html.xpath("//*[@class='bold']")    #  //*表示获取所有标签
for i in res:
    print(i.tag)    #tag表示标签名

47.实战-爬取网络段子

py 复制代码
from lxml import etree
import requests

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36",
    "Accept-Language":"zh-CN,zh;q=0.8"
}

url="https://www.yjbys.com/xiaohua/baoxiao/185139.html"

response=requests.get(url,headers=header).text

html=etree.HTML(response)
res=html.xpath('//div[@class="content"]/p')        #获取class属性为content的div的下一级p元素
for i in res:
    print(i.text)


print("-----------------------------")
res2=html.xpath('//li[@class="excellent_articles_row"]/a/@href')    #获取class属性为excellent_articles_row的li的下一级a元素的href属性
for i in res2:
    response2=requests.get(i,headers=header).text
    html=etree.HTML(response2)
    ppp=html.xpath('//div[@class="content"]/p')
    for j in ppp:
        print(j.text)
    print("-------以下是下一类笑话-------")    


print("-----------------------------")
res3=html.xpath('//div[@class="right_box"]//a/@href')    #获取class属性为right_box的div的所有子孙级a元素的href属性
for i in res3:
    print(i)

47.实战-贴吧图片爬虫(python吧) 说明:用xpath获取不到网页元素,后来采用正则表达式才成功!

py 复制代码
from lxml import etree
import urllib
from urllib import request
import requests
import re

#帖子列表地址:
# https://tieba.baidu.com/f?kw=python&ie=utf-8&pn=0
# https://tieba.baidu.com/f?kw=python&ie=utf-8&pn=50
# https://tieba.baidu.com/f?kw=python&ie=utf-8&pn=100

#单个帖子对应的代码:(获取a标签的href就可以构建单个帖子的链接地址)
# <div class="threadlist_lz clearfix">
#     <div class="threadlist_title pull_left j_th_tit ">
    
#     <a rel="noopener" href="/p/9128826373" title="急急急急急急" target="_blank" class="j_th_tit ">急急急急急急</a>
# </div><div class="threadlist_author pull_right">
#     <span class="tb_icon_author " title="主题作者: xguaoxmgwua" data-field="{&quot;user_id&quot;:3722166603}"><i class="icon_author"></i><span class="frs-author-name-wrap"><a rel="noopener" data-field="{&quot;un&quot;:&quot;xguaoxmgwua&quot;,&quot;id&quot;:&quot;tb.1.1fab66d2.e5dqJf8KKhfC1pBErl8Dyg&quot;,&quot;target_scheme&quot;:null}" class="frs-author-name j_user_card " href="/home/main/?id=tb.1.1fab66d2.e5dqJf8KKhfC1pBErl8Dyg&amp;fr=frs" target="_blank">xguaoxmgwua</a></span><span class="icon_wrap  icon_wrap_theme1 frs_bright_icons "><a style="background: url(https://tb3.bdstatic.com/public/icon/107_14.png?stamp=1723088964) no-repeat -5550px  0;top:0px;left:0px" data-slot="1" data-name="yongyue" data-field="{&quot;name&quot;:&quot;yongyue&quot;,&quot;end_time&quot;:&quot;1727110572&quot;,&quot;category_id&quot;:107,&quot;slot_no&quot;:&quot;1&quot;,&quot;title&quot;:&quot;\u8e0a\u8dc3\u53d1\u8a00\u5370\u8bb0&quot;,&quot;intro&quot;:&quot;\u6ce8\u518c\u540e\u56de\u8d34\u8fbe7\u6b21\uff08\u6bcf\u65e5\u6700\u591a\u8ba1\u65701\u6b21\uff09&quot;,&quot;intro_url&quot;:&quot;http:\/\/tieba.baidu.com\/wxf\/324179?kw=%E5%8D%B0%E8%AE%B0&amp;fr=frsshare&quot;,&quot;price&quot;:0,&quot;value&quot;:&quot;1&quot;,&quot;sprite&quot;:{&quot;1&quot;:&quot;1723088964,111&quot;}}" target="_blank" href="http://tieba.baidu.com/wxf/324179?kw=%E5%8D%B0%E8%AE%B0&amp;fr=frsshare" class="j_icon_slot" title="踊跃发言印记" locate="yongyue_1#icon">  <div class=" j_icon_slot_refresh"></div></a></span>    </span>
#     <span class="pull-right is_show_create_time" title="创建时间">8-13</span>
# </div>
# </div>

#帖子中图片的代码:
# <img class="BDE_Image" src="http://tiebapic.baidu.com/forum/w%3D580/sign=2654fd1e0dfbfbeddc59367748f1f78e/63e8d63f8794a4c201e58b0a48f41bd5ac6e39a9.jpg?tbpicau=2024-08-28-05_6156fc70535745cde6f72fc35e7cca80" size="59656" changedsize="true" width="560" height="457" style="cursor: url(&quot;//tb2.bdstatic.com/tb/static-pb/img/cur_zin.cur&quot;), pointer;">

class spider(object):
    def __init__(self):
        self.tiebaname="python"
        self.begin=1
        self.end=2
        self.url="http://tieba.baidu.com/f?"
        self.header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}
        self.filename=1

    #构造url
    def tiebaSpider(self):
        for page in range(self.begin,self.end+1):
            pn=(page-1)*50
            wo={"pn":pn,"kw":self.tiebaname}
            word=urllib.parse.urlencode(wo)
            myurl=self.url+word+"&ie=utf-8"
            self.loadPage(myurl)

    #爬取页面内容
    def loadPage(self,url):

        response=requests.get(url,headers=self.header)
        data=response.content.decode()
        
        pat=r' <a rel="noopener" href="(.*?)" title=".*?" target="_blank" class="j_th_tit ">'
        links=re.findall(pat,data)
        for link in links:
            link="http://tieba.baidu.com"+link
            self.loadImages(link)


    #爬取帖子详情页,获得图片的链接
    def loadImages(self,link):
    
        response=requests.get(link,headers=self.header)
        data=response.content.decode()
        pat=r'<img class="BDE_Image" src="(.*?)"'
        res=re.findall(pat,data)
        for imgagelink in res:
            self.writeImages(imgagelink)


    #通过图片所在的链接,爬取图片并保存图片到本地
    def writeImages(self,imgagelink):
        print("正在存储图片:",self.filename,"......")
        image=request.urlopen(imgagelink).read()
        file=open(r"d:/pic/"+str(self.filename)+".jpg","wb")    #wb表示以二进制形式打开
        file.write(image)
        file.close()
        self.filename+=1

if __name__ == '__main__':
    myspider=spider()
    myspider.tiebaSpider()

48.BeautifulSoup简介和安装

#CSS选择器:BeautifulSoup

#和lxml一样,BeautifulSoup也是一个HTML/XML的解析器

#主要的功能也是如何解析和提取HTML/XML数据

#模块下载安装:pip install bs4

py 复制代码
from bs4 import BeautifulSoup

html="""
<html><head><title>The story</title></head>
<body>
<p class="title" name="mouse"><b>The story</b></p>
<p class="story">Once a time there were three little sisters
<a href="http://aa.com/elsie" class="sister" id="link1" ><!--Elsie--></a>,
<a href="http://aa.com/lacie" class="sister" id="link2" >Lacie</a>and
<a href="http://aa.com/tilie" class="sister" id="link3" >Tilie</a>;
and they lived at the bottom of a well.</p>
<p class="story">......</p>
"""

#解析字符串形式的html
soup=BeautifulSoup(html,"lxml")

#解析本地html文件
#soup2=BeautifulSoup(open("d:a/index.html"))

#print(soup)    #打印出html文件(会自动补齐缺失的标签)
print(soup.prettify())    #漂亮模式打印出html文件

49.获取标签信息

py 复制代码
from bs4 import BeautifulSoup

html="""
<html><head><title>The story</title></head>
<body>
<p class="title" name="mouse"><b>The story</b></p>
<p class="story">Once a time there were three little sisters
<a href="http://aa.com/elsie" class="sister" id="link1" ><!--Elsie--></a>,
<a href="http://aa.com/lacie" class="sister" id="link2" >Lacie</a>and
<a href="http://aa.com/tilie" class="sister" id="link3" >Tilie</a>;
and they lived at the bottom of a well.</p>
<p class="story">......</p>
"""
 #解析字符串形式的html
soup=BeautifulSoup(html,"lxml")

#根据标签名获取标签信息
print(soup.title)

#获取标签内容
print(soup.title.string)

#获取标签名
print(soup.title.name)

#获取标签内所有属性
print(soup.p.attrs)
print(soup.p.attrs["class"])

#获取head下的直接子标签1,结果是一个列表
print(soup.head.contents)

#获取head下的直接子标签2,结果是一个生成器
for i in soup.head.children:
    print(i)

#获取p标签下所有子标签,结果是一个生成器
for i in soup.p.descendants:
    print(i)

50.搜索文档树

py 复制代码
from bs4 import BeautifulSoup

html="""
<html><head><title>The story</title></head>
<body>
<p class="title" name="mouse"><b>The story</b></p>
<p class="story">Once a time there were three little sisters
<a href="http://aa.com/elsie" class="sister" id="link1" ><!--Elsie--></a>,
<a href="http://aa.com/lacie" class="sister" id="link2" >Lacie</a>and
<a href="http://aa.com/tilie" class="sister" id="link3" >Tilie</a>;
and they lived at the bottom of a well.</p>
<p class="story">......</p>
"""

soup=BeautifulSoup(html,"lxml")

#查找所有a标签,返回一个结果集,里面装的是标签对象(tag)
data=soup.find_all("a")
print(type(data))
for i in data:
    print(i)
    print(i.string)

50.搜索文档树2

py 复制代码
from bs4 import BeautifulSoup
import re

html="""
<html><head><title>The story</title></head>
<body>
<p class="title" name="mouse"><b>The story</b></p>
<p class="story">Once a time there were three little sisters
<a href="http://aa.com/elsie" class="sister" id="link1" ><!--Elsie--></a>,
<a href="http://aa.com/lacie" class="sister" id="link2" >Lacie</a>and
<a href="http://aa.com/tilie" class="sister" id="link3" >Tilie</a>;
and they lived at the bottom of a well.</p>
<p class="story">......</p>
"""

soup=BeautifulSoup(html,"lxml")

#根据正则表达式查找标签
data=soup.find_all(re.compile("^b"))    #查找以b开头的标签

for i in data:
    print(i)

#根据属性查找标签
data2=soup.find_all(id="link2")
for i in data2:
    print(i)

#根据标签内容获取标签内容
data3=soup.find_all(string="Tilie")
print(data3)
data4=soup.find_all(string=["Tilie","Lacie"])
print(data4)
data5=soup.find_all(string=re.compile("ie")) #查找标签内容中包含"ie"二字的所有内容,此例才有实用价值
print(data5)

51.CSS选择器

py 复制代码
from bs4 import BeautifulSoup

html="""
<html><head><title>The story</title></head>
<body>
<p class="title" name="mouse"><b>The story</b></p>
<p class="story">Once a time there were three little sisters
<a href="http://aa.com/elsie" class="sister" id="link1" ><!--Elsie--></a>,
<a href="http://aa.com/lacie" class="sister" id="link2" >Lacie</a>and
<a href="http://aa.com/tilie" class="sister" id="link3" >Tilie</a>;
and they lived at the bottom of a well.</p>
<p class="story">......</p>
"""

soup=BeautifulSoup(html,"lxml")

#通过标签名获取标签,返回一个列表
data=soup.select("a")
print(data[0])

#css选择器种类:标签选择器、类选择器、id选择器

#通过类名查找
data=soup.select(".sister")
print(data)

#通过id查找
data=soup.select("#link1")
print(data)

#组合查找,查找p标签下id为link2的数据
data=soup.select("p #link2")
print(data)

#通过其他属性查找,查找href="http://aa.com/tilie"的a标签数据
data=soup.select('a[href="http://aa.com/tilie"]')
print(data)

52.实战-爬取招聘信息:https://ninghua.597.com/zhaopin/

py 复制代码
from bs4 import BeautifulSoup
from urllib import request

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}

#招聘列表网址:
# https://ninghua.597.com/zhaopin/?page=1
# https://ninghua.597.com/zhaopin/?page=2
# https://ninghua.597.com/zhaopin/?page=3
# ......
# https://ninghua.597.com/zhaopin/?page=6

for i in range(1,7):
    url="https://ninghua.597.com/zhaopin/?page="+str(i)
    req=request.Request(url,headers=header)
    data=request.urlopen(req).read().decode()

#列表中的职位信息:
# <li class="firm-l">
# <label class="pos check-default ptCheck" data-value="7abe4c5699523" data-name="pos"></label>
# <a href="/job-7abe4c5699523.html" data-jid="7abe4c5699523" data-act="1" target="_blank" class="fb des_title" style="" rel="">会计</a></li>
#提取详情地址:https://ninghua.597.com/job-7abe4c5699523.html
    soup=BeautifulSoup(data,"lxml")
    urllist=soup.select('li[class="firm-l"] a')
    for x in urllist:
        url2="https://ninghua.597.com"+x.attrs["href"]    #构建详情页地址
        req2=request.Request(url2,headers=header)
        data2=request.urlopen(req2).read().decode()


#详情页招聘公司信息:
# <p class="newtop1">
# <span>
# <a href="/com-b45c976356242/" target="_blank">飞天有限公司</a>
# <div style="display:none;"></div>
# </span>
# </p>
#详情页招聘职务信息:
# <div class="newtopTit">
# <h2>会计</h2>
# </div>
#详情页招聘职位描述:
# <div class="newTytit">
# <!--<h2>职位描述</h2>-->
# <div style="line-height:30px;">职位描述:<br />负责公司财务往来账务、成本核算、工资发放、财务分析,银行对接,包括对仓库、车间统计数据的审核、汇总、分配、计算等工作。<br />任职要求:<br />(1)男女不限,年龄28---45岁。<br />(2)大专以上学历,财务、会计等相关专业,具有会计师资格证书。<br />(3)掌握国家财经政策和会计、税务法规;具有全面的财务专业知识,财务处理能力。<br />(4)熟练操作电脑办公软件、ERP系统和财务软件。<br />(5)具有2年以上的工业制造业经验者优先考虑.</div>
# </div>
        soup2=BeautifulSoup(data2,"lxml")
        company=soup2.select('p[class="newtop1"] a')[0].get_text()
        job=soup2.select('div[class="newtopTit"] h2')[0].get_text()
        info=soup2.select('div[class="newTytit"] div')[0].get_text()

        print(job,"___",company)
        print(info)
        print("-------------------------------------")

53.往Excel中写数据

py 复制代码
import xlsxwriter

#安装模块:
#pip install xlsxwriter

#创建excel文件,并添加一个工作表
workbook=xlsxwriter.Workbook("demo.xlsx")
worksheet=workbook.add_worksheet()

worksheet.write("A1","我要自学网")
worksheet.write("A2","python教程")

#关闭表格文件
workbook.close()

54.爬虫数据写入Excel

py 复制代码
from bs4 import BeautifulSoup
from urllib import request
import xlsxwriter

header={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36"}

joblist=[]
companylist=[]
infolist=[]

for i in range(1,2):
    url="https://ninghua.597.com/zhaopin/?page="+str(i)    #构建列表页地址
    req=request.Request(url,headers=header)
    data=request.urlopen(req).read().decode()

    soup=BeautifulSoup(data,"lxml")
    urllist=soup.select('li[class="firm-l"] a')
    for x in urllist:
        url2="https://ninghua.597.com"+x.attrs["href"]    #构建详情页地址
        req2=request.Request(url2,headers=header)
        data2=request.urlopen(req2).read().decode()


#获取详情页信息:

        soup2=BeautifulSoup(data2,"lxml")
        company=soup2.select('p[class="newtop1"] a')[0].get_text()
        job=soup2.select('div[class="newtopTit"] h2')[0].get_text()
        info=soup2.select('div[class="newTytit"] div')[0].get_text()

        joblist.append(job)
        companylist.append(company)
        infolist.append(info)

#将数据写入excel
workbook=xlsxwriter.Workbook("demo.xlsx")
worksheet=workbook.add_worksheet()

for i in range(0,len(joblist)):
    worksheet.write("A"+str(i+1),joblist[i])
    worksheet.write("B"+str(i+1),companylist[i])
    worksheet.write("C"+str(i+1),infolist[i])

workbook.close()
print("数据爬取完毕!")

55.多线程回顾

py 复制代码
import threading
import time

def run(name):
    print(name,"执行了!")
    time.sleep(5)

#创建2个线程对象:
t1=threading.Thread(target=run,args=("线程t1",))
t2=threading.Thread(target=run,args=("线程t2",))

#启动线程:
t1.start()
t2.start()

#等待子线程执行完毕后再执行主线程后面的内容:
t1.join()
t2.join()

print("程序完毕!")

56. 机器视觉体验-识别车牌号、人工智能接口申请、文字识别

#一、申请百度AI接口:

#在百度中搜索"baiduai"

#进入百度AI开放平台(https://ai.baidu.com/)

#进入 开发能力-文字识别-通用文字识别

#点击 "立即使用",在弹出窗口中输入登入信息

#点击 "创建应用"

#应用名称设为"图片文字识别",点击"立即创建"

#在应用列表中提取AppID、API Key、Secret Key备用。

#二、安装百度aip模块:

#pip install baidu-aip

#安装后查看有无"Successfully"字样,若无,则没有安装成功,需要采用"To update"方式安装,如下:

py 复制代码
# python.exe -m pip install --upgrade pip


from aip import AipOcr

APP_ID="115507867"
API_KEY="omnSCaoe826t7zHjW4WYbgCP"
SECRET_KEY="YE92MvEhdbsm2J3sYT9A86pkqKHcryuW"

client=AipOcr(APP_ID,API_KEY,SECRET_KEY)

with open(r"D:\img\1.png","rb") as f:    #"rb"表示以二进制打开
    image=f.read()

data=str(client.basicGeneral(image))
print(data)


#注:如果提示:ModuleNotFoundError: No module named 'chardet',
#说明需要安装chardet模块:pip install chardet

#提示Open api qps request limit reached,应该是未付费
#提示No permission to access data,是因为:
#"无权限访问该用户数据,创建应用时未勾选相关接口,请登录百度云控制台,找到对应的应用,编辑应用,勾选上相关接口,然后重试调用"。具体如何操作,不知道!

57.创建线程类

py 复制代码
import threading
import time

class myThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name=name

    def run(self):
        print("开始线程",self.name)
        print("线程执行中---1")
        time.sleep(1)
        print("线程执行中---2")
        time.sleep(1)
        print("线程执行中---3")
        time.sleep(1)
        print("线程执行中---4")
        time.sleep(1)
        print("线程执行中---6")
        time.sleep(1)
        print("线程结束",self.name)

#创建线程:
t1=myThread("t1")
t2=myThread("t2")
t3=myThread("t3")

#开启线程:
t1.start()
t2.start()
t3.start()

#等待子线程执行完毕后再执行主线程后面的内容:
t1.join()
t2.join()
t3.join()

print("执行完毕")

58.队列

py 复制代码
import queue
#queue是python标准库中线程安全的实现
#提供了一个适用于多线程编程的先进先出的数据结构
#用来在生产者和消费者线程之间的信息传递

#创建队列:
q=queue.Queue(maxsize=10)

for i in range(1,11):
    q.put(i) #往队列里放值

#取出队列中的前三个值:
print(q.get())
print(q.get())
print(q.get())

print("--------------")
#循环取出队列中的所有值:
while not q.empty():
    print(q.get())

59.实战-多线程糗事百科爬虫

多线程内容暂时略过...

60.Scrapy框架介绍和安装

Scrapy是用python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,应用非常广泛

框架的优势在于,用户只需要定制开发几个模块就可以轻松实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便。

安装Scrapy框架:pip install Scrapy (会安装很多包,需要较长时间)

60.yield关键字(将方法转化为生成器)

py 复制代码
def f1():
    list=[]
    for i in range(1,6):
        list.append(i)
    return list    #将数据附加(append)到列表后再一起返回。效率比较低,不适用于数据量大的情况

def f2():
    for i  in range(1,6):
        yield i #yield是产出的意思,配合next方法,可以一个一个取出i的值,不需要得到所的有i后才返回,效率更高

print(f1())

gen=f2()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))

61.Scrapy工作流程

1.新建项目(scrapy startproject xxx):新建一个新的爬虫项目

2.明确目标(编写items.py):明确要抓取的目标

3.制作爬虫(spiders/xxxspider.py):制作爬虫开始爬取网页

4.存储内容(pipelines.py):设计管道存储爬取内容

62.创建一个项目

新建项目(scrapy startproject)

开始爬取之前,必须创建一个新的scrapy项目,进入自定义的项目目录中,运行下面命令:

scrapy startproject myspider

其中,myspider为项目名称,将会创建一个myspider文件夹。

注:进入自定义的项目目录运行命令的方法:进入指定目录后,按住shift右击,选择"在此处打开命令窗口(或powershell窗口)",然后执行scrapy startproject myspider命令

下面简单介绍各个主要文件的作用:

scrapy.cfg:项目的配置文件

myspider/:项目的python模块,将会从这里引用代码

myspider/items.py:项目的目标文件

myspider/pipelines.py:项目的管道文件

myspider/settings.py:项目的设置文件

myspider/spiders/:存储爬虫代码目录

myspider/

63.入门案例

py 复制代码
#一、在items.py文件中定义目标数据的字段:
import scrapy
class MyspiderItem(scrapy.Item):
    job=scrapy.Field()  #表示招聘职位
    firm=scrapy.Field() #表示公司名称


#二、在myspider的根目录下按住shift右击,选择"在此处打开命令窗口(或powershell窗口)",然后执行scrapy genspider jobspider ninghua.597.com命令.
#然后在myspider/myspider/spiders/下会出现一个叫"jobspider.py"的文件,这个就是用于写爬虫的文件
#jobspider.py中的代码如下:
import scrapy
class JobspiderSpider(scrapy.Spider):
    name = "jobspider"  #爬虫识别名称
    allowed_domains = ["https://ninghua.597.com"] #爬取网页域名
    start_urls = ["https://ninghua.597.com/zhaopin/?page=1"] #要爬取的url

    def parse(self, response):
        filename="job.html"
        data=response.body  #获取响应内容
        open(filename,"wb").write(data) #写入到本地


#三、在myspider的根目录下按住shift右击,选择"在此处打开命令窗口(或powershell窗口)",然后执行scrapy crawl jobspider命令.
#这样就会在myspider的根目录下出现一个job.html文件,保存了抓取的网页(https://ninghua.597.com/zhaopin/?page=1)

#四、数据清洗:将招聘职位和对应公司名称提取出来
#jobspider.py中的代码改成如下:

import scrapy
import re
#引入items.py中的MyspiderItem类
from myspider.items import MyspiderItem  

class JobspiderSpider(scrapy.Spider):
    name = "jobspider"  #爬虫识别名称
    allowed_domains = ["https://ninghua.597.com"] #爬取网页域名
    start_urls = ["https://ninghua.597.com/zhaopin/?page=1"] #爬取的url

    def parse(self, response):
        data=response.body  #获取响应内容
        items=[]    #存放招聘信息的列表

        jobs=re.findall(r'class="fb des_title" style="" rel="">(.*?)</a>',data) #获取招聘职位
        firms=re.findall(r'target="_blank">(.*?)</a></li>',data) #获取招聘公司名称

        for i in range(0,len(jobs)):
            item=MyspiderItem() #定义一个MyspiderItem类
            item["job"]=jobs[i]
            item["firm"]=firms[i]

           items.append(i)
        return items
     
#在myspider的根目录下按住shift右击,选择"在此处打开命令窗口(或powershell窗口)",然后执行scrapy crawl jobspider -o job.json命令.
#这样就会在myspider的根目录下出现一个job.json文件
相关推荐
拉姆哥的小屋2 小时前
从原子到性能:机器学习如何重塑双金属催化剂的设计范式
人工智能·python·算法·机器学习
小黄编程快乐屋2 小时前
Python 期末复习知识点汇总
java·服务器·python
free-elcmacom2 小时前
机器学习进阶<10>分类器集成:集成学习算法
python·算法·机器学习·集成学习
全栈陈序员2 小时前
【Python】基础语法入门(十八)——函数式编程初探:用 `map`、`filter`、`reduce` 和 `lambda` 写出更简洁的代码
开发语言·人工智能·python·学习
m5655bj2 小时前
如何使用 Python 调整 PDF 页面顺序?
python·pdf
数据科学项目实践2 小时前
建模步骤 3 :数据探索(EDA) — 1、初步了解数据:自定义函数
大数据·人工智能·python·机器学习·matplotlib·数据可视化
我命由我123453 小时前
Python 开发 - OpenAI 兼容阿里云百炼平台 API
开发语言·人工智能·后端·python·阿里云·ai·语言模型
南_山无梅落3 小时前
7.2 Python3序列 | 字符串操作:常用方法与格式化技巧
python
littlezls3 小时前
在VSCode中运行Python脚本文件时如何传参
vscode·python