首页 > 编程语言 >Python爬虫学习-cnblog

Python爬虫学习-cnblog

时间:2022-11-24 22:33:27浏览次数:38  
标签:Python list request 爬虫 urllib page content url cnblog

Python爬虫学习

Python的文件操作

序列化与反序列化

通过文件操作,我们可以将字符串写入到一个本地文件。但是如果是一个对象(列表、字典、元组等),就无法直接写入到一个文件中,需要对这个对象进行序列化,然后才能写入到文件里。

设计一套协议,按照某种规则,把内存中的数据转换为字节序列,保存到文件,这就是序列化;反之,从文件的字节序列恢复到内存中,就是反序列化

Python中提供了JSON这个模块来实现数据的序列化与反序列化

使用JSON实现序列化

JSON提供了dump和dumps方法,将一个对象进行序列化

dumps()方法的作用是把对象转换成字符串,它本身不具备将数据写入到文件的功能

# 对象的序列化
import json
#(1)创建一个文件
fp = open('test.txt','w')

#(2)定义一个列表
fruit_list = ['apple','peach']

# 将Python对象变成json字符串
fruit = json.dumps(fruit_list)
fp.write(fruit)

# 关闭文件
fp.close()

---------------------------------------------
# 用with语句来打开文件
fruit_list = ['apple','peach']
color_tuple = ('puple',99,'blue',100,fruit_list)
color = json.dumps(color_tuple)
with open('test.txt','a') as src_file:
	src_file.write(color)

----------------------------------------------
#dump:在将对象转换为字符串的同时,指定一个文件的对象,然后把转换后的字符串写入到这个文件里
fp = open('text.txt','w')
name_list = ['zs','ls']
# 相当于names = json.dumps(name_list)和fp.write(names)
json.dump(name_list,fp)
fp.close()

Urllib

1.Urlib库使用

  • url.request.urlopen():模拟浏览器向计算机发送请求
  • response :服务器返回的数据
  • response的数据类型是HttpResponse
graph LR 0(字节--字符串)-->1(解码decode) 00(字符串--字节)-->01(编码encode)
  • 读取url的页面源码

    • read():字节形式读取二进制 扩展:read(5)返回前5个字节`
    • readline():读取一行
    • readlines():一行一行读取直至结束
    • getcode():获取状态码
    • geturl():获取url
    • getheaders():获取headers
  • urllib.request.urlretrieve(path,filename)可以请求网页、请求图片和请求视频

2.请求对象的定制

  • UA介绍:User Agent中文名为用户代理,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU类型、浏览器及版本。

  • 语法:request = urllib.request.Request()

3.编解码

1.get请求方式

  • urllibget请求的urllencode()
import urllib.parse
import urllib.request

base_url = 'https://www.baidu.com/s?'

data = {
    'wd': '周杰伦',
    'sex': '男',
    'location': '中国台湾省'
}

new_data = urllib.parse.urlencode(data)
# 请求资源路径
url = base_url + new_data
# UA
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 '
                  'Safari/537.36 Edg/107.0.1418.35 '
}

# 请求对象的定制
request = urllib.request.Request(url=url,headers=headers)

# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
#print(content)

2.post请求方式

  • 注意post请求的参数是不会拼接在url的后面,而是需要放在请求对象定制的参数中
  • 注意事项:
    post请求需要的是字节型,一定要进行编码。
    编码之后必须调用encode方法
# post请求
import urllib.request
import urllib.parse

url = 'https://fanyi.baidu.com/sug'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 '
                  'Safari/537.36 Edg/107.0.1418.35 '
}
data = {
    'kw': 'spider'
}

# post请求的参数必须要进行编码
# urllencode函数将字符串以URL编码
data = urllib.parse.urlencode(data).encode('utf-8')
# post请求的参数 是不会拼接在url的后面,而是需要放在请求对象定制的参数中
request = urllib.request.Request(url=url, data=data, headers=headers)

# 模拟服务器向服务器发送请求
response = urllib.request.urlopen(request)

# 获取响应的数据
content = response.read().decode('utf-8')

# 字符串-->json对象(反序列化)
import  json
obj = json.loads(content)
print(obj)

4.ajax的get请求方式

# 下载豆瓣电影前10页的数据
# (1)请求对象的定制
# (2)获取响应的数据
# (3)下载数据
import urllib.parse
import urllib.request

# 获得get请求的方法
def create_request(page):
    base_url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action='

    data = {
        'start': (page - 1) * 20,
        'limit': 20
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35'
    }
    data = urllib.parse.urlencode(data)
    url = base_url + data
    request = urllib.request.Request(url=url, headers=headers)
    return request

# 获取返回数据的方法
def get_content(request):
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    return content

# 下载数据到本地
def down_load(page, content):
    with open(f'douban{page}.json', 'w', encoding='utf-8') as fp:
        fp.write(content)


# 程序的入口
if __name__ == '__main__':
    start_page = int(input('请输入起始页:'))
    end_page = int(input('请输入结束页:'))

    for page in range(start_page, end_page + 1):
        request = create_request(page)
        content = get_content(request)
        down_load(page, content)

5.ajax的post请求

import urllib.request
import urllib.parse


def create_request(page):
    base_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
    data = {
        'cname': '北京',
        'pid': '',
        'pageIndex': page,
        'pageSize': '10'
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35'
    }
    # url编码
    data = urllib.parse.urlencode(data).encode('utf-8')
    # 获得request请求
    request = urllib.request.Request(url=base_url, data=data, headers=headers)
    return request


def get_content(request):
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    return content


def down_load(page, content):
    with open(f'kfc{page}.json', 'w', encoding='utf-8') as fp:
        fp.write(content)


if __name__ == '__main__':
    start_page = int(input('请输入起始页:'))
    end_page = int(input('请输入结束页:'))

    for page in range(start_page, end_page):
        request = create_request(page)
        content = get_content(request)
        down_load(page,content)

6.URLError/HTTPError

简介:1.HTTPError类是URLError类的子类
	 2.导入的包urllib.error.HTTPError  urllib.error.URLError
     3.http错误:http错误是针对浏览器无法连接到服务器而增加出来的错误提示,引导并告诉浏览者该页是哪里出现了问题
     4.通过urllib发送请求的时候,有可能会发送失败,这个时候如果想让你的代码更加健壮,可以通过try-except进行异常捕获,异常有两类,URLError\HTTPError

7.Handler处理器

前言:urllib.request.urlopen(url)
不能定制请求头
urllib.request.Request(url,headers,data)
可以定制请求头

  • Hander可以定制更高级的请求头(动态cookie和代理不能使用请求对象的定制
import urllib.request

url = 'https://www.baidu.com'

headers = {
    'User-Agent': 'Moz2illa/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35'
}

request = urllib.request.Request(url=url, headers=headers)
# (1)获取handler对象
handler = urllib.request.HTTPHandler()

# (2)获取opener对象
opener = urllib.request.build_opener(handler)
# (3)调用open方法
response = opener.open(request)

content = response.read().decode('utf-8')
print(content)

8.代理服务器

代码配置代理

  • 创建Request对象
  • 创建ProxyHandler对象
  • handler对象创建opener对象
  • 使用opener.open函数发送请求
import urllib.request

url = 'http://www.baidu.com/s?wd=ip'

headers = {
    'User-Agent': 'Moz2illa/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35'
}
# 请求对象的定制
request = urllib.request.Request(url=url, headers=headers)

proxies = {
    'http':'118.24.219.151:16817' #代理ip
}
# (1)获取handler对象
handler = urllib.request.ProxyHandler(proxies=proxies)
# (2)获取opener对象
opener = urllib.request.build_opener(handler)
# (3)调用open方法
response = opener.open(request)
# (4)读取返回内容
content = response.read().decode('utf-8')
# (5)保存
with open('Proxy.html', 'w', encoding='utf-8') as fp:
    fp.write(content)

解析

1.xpath

1.导入lxml.etree
	from lxml import etree
2.解析本地文件:etree.parse()
	html_tree = etree.parse('xx.html')
3.解析服务器响应文件:etree.HTML() 
	html_tree = etree.HTML(response.read().decode('utf-8'))
4.html_tree.xpath(xpath路径)
xpath基本语法:
	1.路径查询:
		//:查找所有子孙节点,不考虑层次关系
		/:找直接子节点
    2.谓词查询
    	//div[@id]
        //div[@id="maincontent"]
    3.属性查询
    	//@class
    4.模糊查询
		//div[contains(@id, "he")]
        //div[starts-with(@id,"he")]
    5.内容查询
    	//div/h1/text()
    6.逻辑运算
		//div[@id = "head" and @class = "s_down"]
        //title | //price
    

案例1:demo.html和xpath.py

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
    <ul>
        <li id="one" class="city">北京</li>
        <li id="two">上海</li>
        <li id="tech">深圳</li>
        <li id="hot">武汉</li>
    </ul>
  <ul>
        <li>大连</li>
        <li>沈阳</li>
        <li>哈尔滨</li>
    </ul>
</body>
</html>
from lxml import etree

# xpath解析本地文件
tree = etree.parse('demo.html')
# 查找所有有id属性的li标签
li_list = tree.xpath('//ul/li[@id]/text()')
print(li_list)
# print(len(li_list))

# 查找到id=""标签中的内容
# text()获取标签中的内容
te_list = tree.xpath('//ul/li[@id="one"]/text()')
print(te_list)

# 查找到id为one的li标签的class的属性值
li = tree.xpath('//ul/li[@id="one"]/@class')
print(li)

# 查询id中包含l的li标签
ct_list = tree.xpath('//ul/li[contains(@id,"e")]/text()')
print(ct_list)

# 查找id中以t开头的Li标签
st_list = tree.xpath('//ul/li[starts-with(@id,"t")]/text()')
print(st_list)

案例2:在网站上爬取图片素材

# 页码分析
# 第三页:https://sc.chinaz.com/tupian/diqiutupian_3.html
# 第一页:https://sc.chinaz.com/tupian/diqiutupian.html (注意不是_1)
import urllib.request
from lxml import etree


def create_request(page):
    if (page == 1):
        url = 'https://sc.chinaz.com/tupian/diqiutupian.html'
    else:
        # url = 'https://sc.chinaz.com/tupian/diqiutupian_'+str(page)+'.html'
        url = f'https://sc.chinaz.com/tupian/diqiutupian_{page}.html'
    # print(url)
    headers = {
        'User-Agent': 'Moz2illa/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35 '
    }
    request = urllib.request.Request(url=url, headers=headers)
    return request


def get_content(request):
    response = urllib.request.urlopen(request)
    content = response.read().decode('utf-8')
    return content


def down_load(content):
    # 下载图片
    # urllib.request.urlretrieve('图片地址','文件名称')
    
    tree = etree.HTML(content)
    name_list = tree.xpath('//div[@class="container"]//img/@alt')
    src_list = tree.xpath('//div[@class="container"]//img/@data-original')
    
    # print(len(name_list),len(src_list))
    for i in range(len(name_list)):
        name = name_list[i]
        src = src_list[i]
        # 加上https头
        url = 'https:' + src
        # 用空格替换_s,因为_s是缩略图
        url = url.replace('_s', '')
        # print(name,url)
        urllib.request.urlretrieve(url=url, filename='./source/' + name + '.jpg')


# //div[@class="container"]//img/@data-original
if __name__ == '__main__':
    st_page = int(input('请输入起始页码:'))
    ed_page = int(input('请输入结束页码:'))

    for page in range(st_page, ed_page + 1):
        # (1)请求对象的定制
        request = create_request(page)
        # (2)获取网页的源码
        content = get_content(request)
        # (3)解析源码并下载图片
        down_load(content)

2JsonPath

(1)jsonpath安装及使用方法

  • pip安装:pip install jsonpath

  • jsonpath的使用:只能解析本地文件,和xpath用法上有区别

    obj = json.load(open('json文件','r',encoding = 'utf-8'))
    ret = jsonpath.jsonpath(obj,'jsonpath语法')
    

(2)jsonpath写法对比

3.BeautifulSoup

  • 和lxml一样,是一个html的解析器,主要功能也是解析和提取数据

(1) 安装和创建

  • 安装 :pip install bs4
  • 导入:from bs4 import BeautifulSoup
  • 创建对象
    • 服务器响应的文件生成对象 soup = BeautifulSoup(response.read().decode,'lxml')
    • 本地文件生成对象soup = BeautifulSoup(open('1.html'),'lxml')

(2) 节点定位

1.根据标签名查找节点  
		soup.a 【注:只能找到第一个a】
		soup.a.attrs 【查找标签a的属性和属性值】
2.函数
		(1).find(返回一个对象)
			find('a'):只找到第一个a标签
			find('a',title = '名字') 
			find('a',class_='名字')
		(2).find_all(返回一个列表)
			find_all('a') 查找到所有的a
			find_all(['a','span']) 返回所有的a和span 
            【注意】如果想要获取多个标签的数据,那么需要在find_all的参数中添加的是列表的数据
			find_all('a',limit = 2) 只找前两个a
3.select(根据选择器得到节点对象)【推荐】
		(1) element    eg:p
        (2) .class	  eg:.firstname
        (3) #id		  eg:#firstname
        (4) 属性选择器
        	[attribute]  eg:li = soup.select('li[class]')
            [attribute=value]  eg:li = soup.select('li[class="hengheng1"]')
        (5) 层级选择器
        	element element(后代选择器)  eg:div p
            element>element(子代选择器)  eg:div>p
            element,element   eg:div,p       

(3) 节点信息

1.获取节点内容:适用于标签中嵌套标签的结构
		obj.get_text()
2.节点的属性
		tag.name 获取标签名
		tag.attrs 将属性作为一个字典返回
3.获取节点属性
		obj.attrs.get('title') 【常用】
    	obj.get('title')
        obj['title']

Selenium

1.selenium的安装

  • 操作edge浏览器驱动下载地址(注意要和edge浏览器版本保持一致)

https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

  • pycharm下载selenium

pip install selenium

2.selenium的使用步骤

(1) 导入 :from selenium import webdriver

(2) 创建edge浏览器操作对象

# 创建浏览器操作对象
path = 'msedgedriver.exe'
# 尝试传参
s = Service(path)
brower = webdriver.Edge(service=s)

(3) 访问网址

url = 'https://www.jd.com/'
brower.get(url)

# page_source获取网页源码
content = brower.page_source

标签:Python,list,request,爬虫,urllib,page,content,url,cnblog
From: https://www.cnblogs.com/epochal/p/girl.html

相关文章

  • Python实验报告(第12章)
      实验12:GUI界面编程一、实验目的和要求1、学会应用常用控件;2、学会使用BoxSizer布局;3、学会事件处理。二、实验环境软件版本:Python3.1064_bit三、实验过程......
  • 爬虫
    企业项目类型#1面向互联网用户:商城类项目 -微信小程序商城#2面向互联网用户:二手交易类的 -咸鱼 -转转#3公司内部项目:python写的重点 -oa系统......
  • 【2022-11-24】爬虫从入门到入狱(二)
    一、request高级用法1.1ssl认证#证书验证(大部分网站都是https)importrequestsres=requests.get('https://www.12306.cn')#如果是ssl请求,首先检查证书是否......
  • 【解决】python获取文件大小,下载进度条报错KeyError: 'content-length'
    python3使用requesthttpx下载文件,获取不到文件大小,response没有content-lengthheader最简单的排查问题的办法就是用浏览器去下载如果浏览器在下载时,也不显示总大小,那......
  • python_03('python基础学习笔记')
    #读取student_grade_input.txt文本文件内容datas=read_file()print("read_filedatas:",datas)#对读取出来的内容可以进行排序datas=sort_grades(datas)print("sort_......
  • 爬虫从入门到入狱(二)
    今日内容概要requests高级用法代理池搭建爬取某视频网站爬取新闻BautifulSoup4介绍bs4遍历文档树今日内容详细requests高级用法ssl认证#https和http有什......
  • 进入python的世界_day38_数据库——mysql约束条件、表关系
    一、字段约束条件1.无负号​ unsignedcreatetablet(idintunsigned);#不能添加负数2.零填充​ zerofillcreatetablet(idintzerofill);#填入得数据展......
  • python_list列表
     列表list关键字in和notin用来判断元素是否包含在列表list中,str也能使用list_city01=["北京","北京","杭州"]#判断数据在列表中print("北京"inlist_ci......
  • HDU:1091 的 python3 和 golang 实现
    python3defhdu_1091():whileTrue:s=input("input")s1=s.split("")ifs1[0]=="0"ands1[1]=="0":break......
  • python_02
    #(实用技能)按照文件后缀名整理文件夹#怎么获取文件的后缀名:importos#os.path.splitext("/path/to/aaa.mp3")#输出:(“/path/to/aaa“,......