Python 爬虫

爬虫

爬虫:通过编写程序来获取互联网上的资源

举例:简单爬百度

from urllib.request import urlopen
#导入一个包
url="http://www.baidu.com"
resp=urlopen(url) #打开一个网址
# print(resp.read().decode("utf-8")) #将解码转换成字符串输出

with open("mybaidu.html",mode="w",encoding="utf-8") as f:
    f.write(resp.read().decode("utf-8")) #读取到网页的页面源代码
#将爬取的内容写入文件
print("over!")
resp.close()

爬取百度数据
在这里插入图片描述
html文件运行后可得百度网页
在这里插入图片描述
哇哦,简直一模一样

一、Requests请求

注意:requests需要安装!!
  安装requests:pip install requests
  国内源:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

1.Web请求过程剖析

1.服务器渲染:在服务器那边直接把数据和html整合在一起,统一返回给浏览器
       在页面源代码中能看到数据
2.客户端渲染:第一次请求只要一个html骨架,第二次请求拿到数据,进行数据拓展
       在页面源代码中,看不到数据

2.requests请求方式

①get()

举例:1.从搜狗浏览器请求 “ XXX ” 获得查询结果

import requests
# get方式适用
query=input("请输入:")
url=f"https://www.sogou.com/web?query={query}"
dic={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"}
#User-Agent:设备
resp=requests.get(url,headers=dic) #获取网站源码 headers=dic实现了一个小小的反爬
print(resp)  #<Response [200]>表示发送请求成功
print(resp.text)  #获取页面源代码
resp.close()

获得有关 “ 黄晓明 ” 的页面源代码
在这里插入图片描述
2.从豆瓣电影网页爬取数据

import requests
url2="https://movie.douban.com/j/chart/top_list?"
#重新封装参数
param={
    "type": 24,
    "interval_id": "100:90",
    "action": "",
    "start": 0,
    "limit": 20,
}
header={
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
resp2=requests.get(url2,params=param,headers=header)
# print(resp2.text)  #若无输出情况,被反爬
print(resp2.json())
resp2.close()  #访问页面后要关闭请求
④post()

举例:百度翻译翻译单词

import requests
#post方式适用
url1="https://fanyi.baidu.com/sug"
og=input("请输入你要翻译的单词:")
dat={
    "kw":og
}
#发送post请求,发送的数据必须放在字典中,通过data参数进行传递
resp1=requests.post(url1,data=dat)
print(resp1.json())  #resp1.json()将服务器返回的内容直接转换成python里的字典
resp1.close()

在这里插入图片描述

二、数据解析

数据解析方式:
①.re解析(Regular Expression):
  正则表达式,一种使用表达式的方式对字符串进行匹配的语法规则
  元字符:具有固定含义的特殊字符,每个元字符默认只匹配一个字符串
  量词:控制元字符出现的次数
  贪婪匹配:.*
  惰性匹配:.*?
②.bs4解析
③.xpath解析

1.re解析:

①正则表达式

1.常用元字符
在这里插入图片描述
2.量词
在这里插入图片描述

②主要方法

1.findall:匹配字符串中所有符合正则的内容,返回的列表

lst=re.findall(r"\d+","我的电话号码是15565151,我爸爸的电话号码是13513444")
print(lst)  #['15565151', '13513444']

2.finditer:匹配字符串中所有的内容,返回的是迭代器

it=re.finditer(r"\d+","我的电话号码是15565151,我爸爸的电话号码是13513444")
print(it)  #<callable_iterator object at 0x000001F864685430>
for i in it:
    print(i.group())

3.search:找到一个结果就返回,返回对象的结果是match对象,拿数据需要.group()

s=re.search(r"\d+","我的电话号码是15565151,我爸爸的电话号码是13513444")
print(s.group())

4.match:从头开始匹配,如果开头第一个不符合类型则报错,相当于正则表达式中的^

m=re.match(r"\d+","15565151是我的电话号码,我爸爸的电话号码是13513444")
print(m.group())

5.compile:预加载正则表达式

obj=re.compile(r"\d+")

ret=obj.findall("我的电话号码是15565151,我爸爸的电话号码是13513444")
print(ret)
ret1=obj.search("我是你爸爸1561号,1456煞笔")
print(ret1.group())
③举例

#单独获取到正则中的具体内容可以给分组起名字
#(?P<分组名字>正则) 可以单独从正则匹配内容中进一步提取内容

s = """
<div class="QQ"><span id="01">数据化</span></div>
<div class="WW"><span id="02">美化</span></div>
<div class="EE"><span id="03">可视化</span></div>
"""
obj = re.compile(r"<div class=\".*?\"><span id=\"\d+\">(?P<name>.*?)</span></div>", re.S)  #re.S让.可以匹配换行符
result = obj.finditer(s)
for it in result:
    print(it.group())
    print(it.group("name"))

注意!!!
调用re的方法必须导入re模块

import re

三、re应用

1.手刃豆瓣top250排行

import requests
import re
import csv
url = "https://movie.douban.com/top250"
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
resp = requests.get(url, headers=header)
page_content = resp.text  # 页面源代码
# 解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)'
                 r'</span>.*?<p class="">.*?<br>(?P<year>.*?)'
                 r'&nbsp;.*?<span class="rating_num" property="v:average">(?P<score>.*?)'
                 r'</span>.*?<span>(?P<num>.*?)</span>', re.S)
# 开始匹配
result = obj.finditer(page_content)
f=open("data.csv",mode="w")
csvwrite=csv.writer(f)
for it in result:
    # print(it.group("name"),"\n",it.group("year").strip(),"\n",it.group("score"),"\n",it.group("num"))
    dic=it.groupdict()
    dic['year']=dic['year'].strip()
    csvwrite.writerow(dic.values())
    #将数据写入csv文件中
f.close()
resp.close()
print("over")

csv文件存储数据
在这里插入图片描述

2.获取天堂电影信息

注:多重获取,爬取子网页数据

import requests
import re
domain = "https://www.dy2018.com/"
resp = requests.get(domain, verify=False)  # 直接get获取不到,会报错,因为网页有防火墙
resp.encoding = "gb2312"  # 指定字符集编码格式
# print(resp.text)

# 拿到ul里面的li
obj1 = re.compile(r"2021必看热片.*?<ul>(?P<ul>.*?)</ul>", re.S)
obj2 = re.compile(r"<a href='(?P<href>.*?)'", re.S)
obj3 = re.compile(r'<br />◎片  名(?P<name>.*?)<br />.*?<td style="WORD-WRAP: break-word" bgcolor="#fdfddf"><a href="(?P<downlaod>.*?)">', re.S)
result1 = obj1.finditer(resp.text)
child_href_list = []
for it in result1:
    ul = it.group("ul")
    # 提取子页面链接
    result2 = obj2.finditer(ul)
    for itt in result2:
        # 拼接子页面的url地址 : 域名 + 子页面地址
        child_href = domain + itt.group("href").strip("/")  # .strip("/")表示去掉/
        child_href_list.append(child_href)  # 把子页面链接保存起来

# 提取子页面内容
for href in child_href_list:
    child_resp = requests.get(href, verify=False)
    child_resp.encoding = 'gb2312'
    result3 = obj3.search(child_resp.text)
    print(result3.group("name"))
    print(result3.group("downlaod"))
    # break  # 测试用

resp.close()

运行结果存在警告信息:因为天堂电影存在防火墙及其他反爬程序
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值