爬虫01
作者:互联网
爬虫笔记
爬虫分类
-
通用网络爬虫(搜索引擎使用,遵守robots协议)
robots协议:网站通过robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,通过网络爬虫需要遵守robots协议。
实例:www.baidu.con/robots.txt
-
聚焦网络爬虫:自己写爬虫程序
爬虫数据步骤
- 确定需要爬取的URL地址
- 有请求模块向URL地址发出请求,并得到网站响应。
- 从响应中提取数据
- 所需数据,保存
- 页面中有其它需要跟进的URL地址,继续第二部请求,如此循环
爬虫模块
requests模块
- 常用方法
requests.get()
【1】作用
向目标网站发起请求,并获取对象
【2】参数
url:需要抓取url地址
headers:请求头
timeout:超时时间,超时会抛出异常
http://httpbin.org/get这是测试网站可以返回请求数据
响应参数
import requests
result = requests.get('https://www.jd.com/')
# content响应内容为bytes,decode('utf-8')然后用utf-8解码
result = requests.get('https://www.jd.com/').content.decode('utf-8')
# text响应字符串
result = result.text
# content响应内容为bytes,爬取图片、音频、文件、视频
result = result.content
# http响应码result.status_code
code = result.status_code
print(code)
urllib.parse模块
这个库作用:url地址中有中文的可以对URL地址解码
from urllib import parse
params = parse.urlencode({'wd':'赵丽颖','pn':'10'})
print(params)
输出**************
#多个参数中间&符号会自动加上
wd=%E8%B5%B5%E4%B8%BD%E9%A2%96&pn=10
快速生成拼接URL
import requests
from urllib import parse
url = 'www.baidu.com/s?{}'
for i in range(1,101):
page = (i-1)*10
params = parse.urlencode({'wd': '赵丽颖', 'pn': str(page)})
page_url = url.format(params)
print(page_url)
*********************部分输出***********************
www.baidu.com/s?wd=%E8%B5%B5%E4%B8%BD%E9%A2%96&pn=0
www.baidu.com/s?wd=%E8%B5%B5%E4%B8%BD%E9%A2%96&pn=10
www.baidu.com/s?wd=%E8%B5%B5%E4%B8%BD%E9%A2%96&pn=20
www.baidu.com/s?wd=%E8%B5%B5%E4%B8%BD%E9%A2%96&pn=30
unquote(string)解码
#将编码后的字符串转为普通的unicode字符串
import requests
from urllib import parse
params = '%E8%B5%B5%E4%B8%BD%E9%A2%96'
result = parse.unquote(params)
*********************部分输出***********************
赵丽颖
案例:输入明星名称、开始页数、结束页数,爬取HTML到本地
【1】查看所抓取的数据在响应内容中是否存在,应为现在有好多数据时动态加载出来
右键--查看网页源代码--搜索关键字
【2】查找并分析URL规律
【3】发送请求并获取响应内容
import requests
from urllib import parse
import time
import random
class BaiduTieba():
def __init__(self):
# https://tieba.baidu.com/f?kw=%E8%B5%B5%E4%B8%BD%E9%A2%96&pn=100
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/87.0.4280.141 Safari/537.36'}
def get_html(self, url, header):
result = requests.get(url, headers=self.header).content.decode('utf-8')
return result
def parse_html(self):
# 数据解析处理
pass
def save_html(self, filename, html):
with open(filename, 'w') as f:
f.write(html)
def run(self):
name = input('请输入明星名称:')
start_page = input("请输入开始页数:")
end_page = input("请输入结束页数:")
# 解析URL和请求
for page in range(int(start_page), int(end_page) + 1):
pn = (page - 1) * 50
#解码有中文URL并拼接页数
params = parse.urlencode({'kw': name, 'pn': str(pn)})
url = self.url.format(params)
html = self.get_html(url, self.header)
filename = '{}第{}页.html'.format(name, page)
with open(filename, 'w', encoding='utf-8')as f:
f.write(html)
# 请求速度太快,随机休眠1-3秒
time.sleep(random.randint(1, 3))
if __name__ == '__main__':
sider = BaiduTieba()
sider.run()
正则表达式
re模块使用流程
# 方法一,这个是常用,re.S作用:让正则表达式. 能匹配\n
r_list = re.findall('正则表达式',html,re.S)
# 方法二
pattern = re.compile('正则表达式',html,re.S)
例子:
import re
r_list = re.findall('AB','ABCABCABCDEFG')
print(r_list)
*********************部分输出***********************
['AB', 'AB', 'AB']
思考:请写出匹配任意一个字符正则表达式
import re
r_list = re.findall('.',html,re.S)
贪婪匹配和非贪婪匹配
-
贪婪匹配(默认)
1、在整个表达式匹配成功的前提下,尽可能多的匹配 * + ? 2、表示方式: .* .+ .?
-
非贪婪匹配
1、在整个表达式匹配成功的前提下,尽可能少的匹配 * + ? 2、表示方式: .*? .+? .??
-
案例
把文字抓取出来,一个元素一段文字
import re html = """ <div><p>你动我一下试试,我屠你满门</p></div> <div><p>你动她一下试试,我屠尽全世界</p></div> """ r_list = re.findall('<div><p>.*</p></div>', html, re.S) print(r_list) *********************部分输出*********************** ['<div><p>你动我一下试试,我屠你满门</p></div>\n<div><p>你动她一下试试,我屠尽全世界</p></div>']
# 把正则匹配模式改成,非贪婪模式 import re html = """ <div><p>你动我一下试试,我屠你满门</p></div> <div><p>你动她一下试试,我屠尽全世界</p></div> """ r_list = re.findall('<div><p>.*?</p></div>', html, re.S) print(r_list) *********************部分输出*********************** ['<div><p>你动我一下试试,我屠你满门</p></div>', '<div><p>你动她一下试试,我屠尽全世界</p></div>']
# 匹配加了括号,变成正则表达式分组,只提取匹配内容出来 import re html = """ <div><p>你动我一下试试,我屠你满门</p></div> <div><p>你动她一下试试,我屠尽全世界</p></div> """ r_list = re.findall('<div><p>(.*?)</p></div>', html, re.S) print(r_list) *********************部分输出*********************** ['你动我一下试试,我屠你满门', '你动她一下试试,我屠尽全世界']
正则表达式分组
-
作用
在完整的模式中第一子模式,将每个园括号中子模式匹配出来的结果提取出来
-
案例
import re s = 'A B C D E F G' r_list = re.findall('\w+\s+\w+', s, re.S) print(r_list) *********************部分输出*********************** [('A', 'B'), ('C', 'D'), ('E', 'F')] ************************************************** r_list = re.findall('(\w+)\s+\w+', s, re.S) print(r_list) *********************部分输出*********************** ['A', 'C', 'E'] ************************************************** r_list = re.findall('(\w+)\s+(\w+)', s, re.S) print(r_list) *********************部分输出*********************** [('A', 'B'), ('C', 'D'), ('E', 'F')] **************************************************
-
分组总结
1、在网页中,想要什么内容,就加() 2、先按整体正则匹配,然后在提取分组()内容 3、如果有两个以上分组(),则结果中以元祖形式显示[(),(),()]
-
案例
#爬取猫眼电影top100数据(电影名称、主演、上映时间) import requests import re import time import random url = 'https://maoyan.com/board/4?offset={}' #headers要稍微全的,不然又可能会验证 headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Host': 'maoyan.com', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-User': '?1', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36' } for page in range(10): url = 'https://maoyan.com/board/4?offset={}' offset = page * 10 url = url.format(str(offset)) result = requests.get(url, headers=headers).content.decode('utf-8') #删除内容要加.*? 抓取数据要加(.*?) re_list = re.findall('<dd>.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?class="releasetime">(.*?)</p>', result,re.S) print(re_list) time.sleep(random.randint(1, 5))
标签:01,url,list,爬虫,re,html,import,B5% 来源: https://www.cnblogs.com/Hi-Son/p/14260169.html