python爬虫
一、Urllib
1、互联网爬虫
- 解释1:通过一个程序,根据Url(http://www.taobao.com)进行爬取网页,获取有用信息。
- 解释2:使用程序模拟浏览器,去向服务器发送请求,获取响应信息。
2、爬虫的核心
- 爬取网页:爬取整个网页,包含了网页中所有的内容。
- 解析数据:将网页中得到的数据进行解析。
- 难点:爬虫和反爬虫之间的博弈。
3、爬虫的用途
- 数据分析/人工数据集
- 社交软件冷启动
- 舆情监控
- 竞争对手监控
4、爬虫分类
1)通用爬虫:
实例:百度、360、google、sougou等搜索引擎
功能:访问网页‐>抓取数据‐>数据存储‐>数据处理‐>提供检索服务
robots协议:一个约定俗成的协议,添加robots.txt文件,来说明本网站哪些内容不可以被抓取,起不到限制作用,自己写的爬虫无需遵守。
网站排名(SEO):
- 根据pagerank算法值进行排名(参考网站流量、点击率等指标)
- 百度竞价排名
缺点:
- 抓取的数据大多是无用的
- 不能根据用户的需求来精准获取数据
2)聚焦爬虫
功能:根据需求,实现爬虫程序,抓取需要的数据
设计思路:
1.确定要爬取的url。
2.模拟浏览器通过http协议访问url,获取服务器返回的html代码。
3.解析html字符串(根据一定规则提取需要的数据)。
5、反爬手段
1)User‐Agent
User Agent:中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
2)代理IP
西刺代理、快代理
什么是高匿名、匿名和透明代理?它们有什么区别?
- 使用透明代理,对方服务器可以知道你使用了代理,并且也知道你的真实IP。
- 使用匿名代理,对方服务器可以知道你使用了代理,但不知道你的真实IP。
- 使用高匿名代理,对方服务器不知道你使用了代理,更不知道你的真实IP。
3)验证码访问
打码平台、云打码平台
4)动态加载网页
网站返回的是js数据,并不是网页的真实数据
5)数据加密
分析js代码
6、urllib库的使用
urllib.request.urlopen()
模拟浏览器向服务器发送请求
response
服务器返回的数据
response
的数据类型是 HttpResponse
- 字节→字符串:解码decode
- 字符串→字节:编码encode
方法 | 作用 |
---|---|
read() |
字节形式读取二进制 扩展:rede(5)返回前几个字节 |
readline() |
读取一行 |
readlines() |
一行一行读取,直至结束 |
getcode() |
获取状态码 |
geturl() |
获取url |
getheaders() |
获取headers |
urllib.request.urlretrieve()
请求网页、请求图片、请求视频
7、请求对象的定制
UA介绍:User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等。
语法:request = urllib.request.Request()
8、编解码
1)get请求方式:urllib.parse.quote()
import urllib.request
import urllib.parse
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
url = 'https://www.baidu.com/s?wd='
keyword = urllib.parse.quote('周杰伦')
url = url + keyword
print(url)
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
2)get请求方式:urllib.parse.urlencode()
import urllib.request
import urllib.parse
url = 'https://www.baidu.com/s?'
data = {
'wd': '周杰伦',
'age': '42',
'location': '中国台湾'
}
url = url + urllib.parse.urlencode(data)
# print(url)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
3)post请求方式
import urllib.request
import urllib.parse
import json
url = 'https://fanyi.baidu.com/sug'
data = {
'kw': 'spider'
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
# post的请求参数必须要进行编码
data = urllib.parse.urlencode(data).encode('utf-8')
request = urllib.request.Request(url=url, data=data, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
content = json.loads(content)
print(content['data'][0]['v'])
4)post和get区别
- get请求方式的参数必须编码,参数是拼接到url后面,编码之后不需要调用encode方法。
- post请求方式的参数必须编码,参数是放在请求对象定制的方法中,编码之后需要调用encode方法。
9、ajax的get请求
import urllib.parse
import urllib.request
def creat_request(page_arg):
url = 'https://movie.douban.com/j/chart/top_list?type=13&interval_id=100%3A90&action=&'
data = {
'start': (page_arg - 1) * 20,
'limit': 20
}
url = url + urllib.parse.urlencode(data)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
return urllib.request.Request(url=url, headers=headers)
def get_content(request_arg):
response = urllib.request.urlopen(request_arg)
return response.read().decode('utf-8')
def download(page_arg, content_arg):
with open('douban_' + str(page_arg) + '.json', 'w', encoding='utf-8') as fp:
fp.write(content_arg)
if __name__ == '__main__':
start_page = int(input('请输入起始页码:'))
end_page = int(input('请输入结束页码:'))
for page in range(start_page, end_page + 1):
request = creat_request(page)
content = get_content(request)
download(page, content)
10、ajax的post请求
import urllib.request
import urllib.parse
def create_request(arg_page):
url = 'https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
data = {
'cname': '广州',
'pid': '',
'pageIndex': str(arg_page),
'pageSize': '10'
}
data = urllib.parse.urlencode(data).encode('utf-8')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
request = urllib.request.Request(url=url, data=data, headers=headers)
return request
def get_content(arg_request):
response = urllib.request.urlopen(arg_request)
content = response.read().decode('utf-8')
return content
def download(arg_page, arg_content):
with open('kfc_' + str(arg_page) + '.json', 'w', encoding='utf-8') as fp:
fp.write(arg_content)
if __name__ == '__main__':
for page in range(1, 4):
created_request = create_request(page)
geted_content = get_content(created_request)
download(page, geted_content)
11、URLErrorHTTPError
- HTTPError类是URLError类的子类。
- 导入的包
urllib.error.HTTPError
、urllib.error.URLError
。 - http错误:http错误是针对浏览器无法连接到服务器而增加出来的错误提示。引导并告诉浏览者该页是哪里出了问题。
- 通过urllib发送请求的时候,有可能会发送失败,这个时候如果想让你的代码更加的健壮,可以通过try‐except进行捕获异常,异常有两类,
URLError
HTTPError
。
import urllib.request
import urllib.error
url = 'https://blog.csdn.net/m0_52503067/article/details/1308872711'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
try:
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
except urllib.error.HTTPError:
print('系统正在维护中……')
import urllib.request
import urllib.error
url = 'https://www.yixinchd.com'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
try:
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
except urllib.error.URLError:
print('系统正在升级中……')
12、cookie登录
import urllib.request
# 适用的场景:进行数据采集的时候,需要绕过登录,然后进入某个页面
url = 'https://weibo.cn/6348128187/info'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36',
'Cookie': 'SUB=_2A25IkTqmDeRhGeBN71oQ8ibNwzuIHXVr7zJurDV6PUJbktANLVPfkW1NRH7w-XCjbRc1bX9unbhvkaNW9jZBFLqP; SUBP=00'
'33WrSXqPxfM725Ws9jqgMF55529P9D9W5UG-o5opBbliwJzv9ep.M35JpX5KzhUgL.Foq0Shnpeonp1hM2dJLoIEBLxKBLB.zLBK-Lx'
'K-LB.qL1heLxK-L1K5L12eLxK-LB-BLBKqt; SSOLoginState=1704282870; _T_WM=88327e172a5590f58515f50a61044399; '
'MLOGIN=1'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
with open('weibo.html', 'w', encoding='utf-8') as fp:
fp.write(content)
13、Handler处理器
urllib.request.urlopen(url)
不能定制请求头。urllib.request.Request(url,headers,data)
可以定制请求头。Handler
定制更高级的请求头。随着业务逻辑的复杂,请求对象的定制已经满足不了我们的需求,动态cookie和代理不能使用请求对象的定制。
# 需求:使用handler访问百度,获取网页源码
import urllib.request
url = 'https://www.baidu.com'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
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')
with open('handler.html', 'w', encoding='utf-8') as fp:
fp.write(content)
14、代理服务器
1)代理的常用功能
- 突破自身IP访问限制,访问国外站点。
- 访问一些单位或团体内部资源
扩展:某大学FTP(前提是该代理地址在该资源的允许访问范围之内),使用教育网内地址段免费代理服务器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。 - 提高访问速度
扩展:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。 - 隐藏真实IP
扩展:上网者也可以通过这种方法隐藏自己的IP,免受攻击。
2)代码配置代理
- 创建Reuqest对象
- 创建ProxyHandler对象
- 用handler对象创建opener对象
- 使用opener.open函数发送请求
import urllib.request
import urllib.parse
url = 'https://www.baidu.com/s?wd=ip'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
# response = urllib.request.urlopen(request)
proxies = {
'http': '121.41.8.23:16817'
}
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
with open('dali.html', 'w', encoding='utf-8') as fp:
fp.write(content)
3)代理池
import urllib.request
import random
url = 'https://www.baidu.com/s?wd=ip'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
proxies_poll = [
{'http': '121.41.8.23:16817'},
{'http': '121.41.8.23:16817'},
]
proxies = random.choice(proxies_poll)
# print(proxies)
request = urllib.request.Request(url=url, headers=headers)
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
with open('daili.html', 'w', encoding='utf-8') as fp:
fp.write(content)
二、解析
1、xpath
xpath基本语法
- 路径查询
//:查找所有子孙节点,不考虑层级关系
/ :找直接子节点 - 谓词查询
//div[@id]
//div[@id=“maincontent”] - 属性查询
//@class - 模糊查询
//div[contains(@id, “he”)]
//div[starts‐with(@id, “he”)] - 内容查询
//div/h1/text() - 逻辑运算
//div[@id=“head” and @class=“s_down”]
//title | //price
获取百度首页的百度一下
import urllib.request
from lxml import etree
url = 'https://www.baidu.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/120.0.0.0 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
tree = etree.HTML(content)
result = tree.xpath('//span/input[@id="su"]/@value')[0]
print(result)
获取站长素材的一些图片
原文地址:https://blog.csdn.net/m0_52503067/article/details/135352203
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_53116.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!