python爬虫系列 —— 一些常用语法的实现总结

目录

一、requests模块用法

1、get请求

2、post请求

3、封装参数请求

二、爬虫解析器的三种方式

1、re模块

2、BeautifulSoup模块

3、xpath模块

三、selenium模块用法

1、基本用法

2、下拉框数据获取

3、登录验证码识别


一、requests模块用法

1、get请求

# 安装requests
# pip install requests
# 国内源
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
import requests

# 1、get获取搜索信息
url = "https://www.sogou.com/web?query=周杰伦"

headers_value = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"
}
resp = requests.get(url, headers=headers_value)
print(resp.text)
# 关闭连接
resp.close()

2、post请求

import requests

url = "https://fanyi.baidu.com/sug"

s = input("请输入你要翻译的英文单词")
dat = {
    "kw": s
}

# 发送post请求, 发送的数据必须放在字典中, 通过data参数进行传递
resp = requests.post(url, data=dat)
print(resp.json())  # 将服务器返回的内容直接处理成json()  => dict

# 关闭连接
resp.close()

3、封装参数请求

import requests

url = "https://movie.douban.com/j/chart/top_list"

# 重新封装参数
param = {
    "type": "24",
    "interval_id": "100:90",
    "action": "",
    "start": 0,
    "limit": 20,
}

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}

resp = requests.get(url=url, params=param, headers=headers)

print(resp.json())
# 关闭连接
resp.close()

二、爬虫解析器的三种方式

         re 利用正则匹配,在性能上远比 xpath bs4 高很多,但是在使用上难度较大,且后期维护的困难度也高很多;bs4 实际情况需要转换过程,在层数多且量大的情况下,实际效率 xpath 要比 bs4 高很多。总的来说,xpath 加上 scrapy-redis 的分布式已经非常满足性能要求了,建议入 xpath 的坑。

1、re模块

import re

# # findall:  匹配字符串中所有的符合正则的内容
# lst = re.findall(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# print(lst)
#
# # finditer: 匹配字符串中所有的内容[返回的是迭代器], 从迭代器中拿到内容需要.group()
# it = re.finditer(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# for i in it:
#     print(i.group())

# # search, 找到一个结果就返回, 返回的结果是match对象. 拿数据需要.group()
# s = re.search(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# print(s.group())


# # match是从头开始匹配
# s = re.match(r"\d+", "10086, 我女朋友的电话是:10010")
# print(s.group())

# # 预加载正则表达式
# obj = re.compile(r"\d+")
#
# ret = obj.finditer("我的电话号是:10086, 我女朋友的电话是:10010")
# for it in ret:
#     print(it.group())
#
# ret = obj.findall("呵呵哒, 我就不信你不换我1000000000")
# print(ret)

s = """
<div class='jay'><span id='1'>郭麒麟</span></div>
<div class='jj'><span id='2'>宋铁</span></div>
<div class='jolin'><span id='3'>大聪明</span></div>
<div class='sylar'><span id='4'>范思哲</span></div>
<div class='tory'><span id='5'>胡说八道</span></div>
"""

# (?P<分组名字>正则) 可以单独从正则匹配的内容中进一步提取内容
obj = re.compile(r"<div class='.*?'><span id='(?P<id>\d+)'>(?P<wahaha>.*?)</span></div>", re.S)  # re.S: 让.能匹配换行符

result = obj.finditer(s)
for it in result:
    print(it.group("wahaha"))
    print(it.group("id"))

2、BeautifulSoup模块

# 安装
# pip install bs4 -i 清华

# 1. 拿到页面源代码
# 2. 使用bs4进行解析. 拿到数据
import requests
from bs4 import BeautifulSoup
import csv

url = "http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml"
resp = requests.get(url)

f = open("菜价.csv", mode="w")
csvwriter = csv.writer(f)

# 解析数据
# 1. 把页面源代码交给BeautifulSoup进行处理, 生成bs对象
page = BeautifulSoup(resp.text, "html.parser")  # 指定html解析器
# 2. 从bs对象中查找数据
# find(标签, 属性=值)
# find_all(标签, 属性=值)
# table = page.find("table", class_="hq_table")  # class是python的关键字
table = page.find("table", attrs={"class": "hq_table"})  # 和上一行是一个意思. 此时可以避免class
# 拿到所有数据行
trs = table.find_all("tr")[1:]
for tr in trs:  # 每一行
    tds = tr.find_all("td")  # 拿到每行中的所有td
    name = tds[0].text  # .text 表示拿到被标签标记的内容
    low = tds[1].text  # .text 表示拿到被标签标记的内容
    avg = tds[2].text  # .text 表示拿到被标签标记的内容
    high = tds[3].text  # .text 表示拿到被标签标记的内容
    gui = tds[4].text  # .text 表示拿到被标签标记的内容
    kind = tds[5].text  # .text 表示拿到被标签标记的内容
    date = tds[6].text  # .text 表示拿到被标签标记的内容
    csvwriter.writerow([name, low, avg, high, gui, kind, date])

f.close()
print("over1!!!!")


3、xpath模块

import lxml.html
etree = lxml.html.etree

tree = etree.parse("b.html")
# result = tree.xpath('/html')
# result = tree.xpath("/html/body/ul/li/a/text()")
# result = tree.xpath("/html/body/ul/li[1]/a/text()")  # xpath的顺序是从1开始数的, []表示索引

# result = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()")  # [@xxx=xxx] 属性的筛选

# print(result)

# ol_li_list = tree.xpath("/html/body/ol/li")
#
# for li in ol_li_list:
#     # 从每一个li中提取到文字信息
#     result = li.xpath("./a/text()")  # 在li中继续去寻找. 相对查找
#     print(result)
#     result2 = li.xpath("./a/@href")  # 拿到属性值: @属性
#     print(result2)
#
# print(tree.xpath("/html/body/ul/li/a/@href"))

print(tree.xpath('/html/body/div[1]/text()'))
print(tree.xpath('/html/body/ol/li/a/text()'))

三、selenium模块用法

    selenium可以模拟浏览器登录,点击,搜索等操作,配合xpath更为人性化,我们不必查找数据真实地址,而是直接读取浏览器已经解析好的数据,缺点是慢而且容器反爬。

1、基本用法

from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

web = Chrome()
web.get("http://www.lagou.com")
# 1、找到某个元素. 点击它
el = web.find_element(By.XPATH, '//*[@id="changeCityBox"]/p[1]/a').click()
time.sleep(1)

# 2、找到输入框. 输入python  =>  输入回车/点击搜索按钮
web.find_element(By.XPATH, '//*[@id="search_input"]').send_keys("python", Keys.ENTER)

# 3、查找存放数据的位置. 进行数据提取
li_list = web.find_elements(By.XPATH, '//*[@id="jobList"]/div[1]/div')
for li in li_list:
    job_name = li.find_element(By.XPATH, './div[1]/div[1]/div[1]/a').text
    job_price = li.find_element(By.XPATH, './div[1]/div[1]/div[2]/span').text
    company_name = li.find_element(By.XPATH, './div[1]/div[2]/div[1]/a').text
    print(company_name, job_name, job_price)

# 4、如何进入到新窗口中进行提取
# 注意, 在selenium的眼中. 新窗口默认是不切换过来的.【-1】表示切换到最后一个窗口也就是新窗口
web.switch_to.window(web.window_handles[-1])
# 在新窗口中提取内容
job_detail = web.find_element_by_xpath('//*[@id="job_detail"]/dd[2]/div').text
print(job_detail)

# 5、如何从新窗口切回来
# 关掉子窗口
web.close()
# 变更selenium的窗口视角. 回到原来的窗口中
web.switch_to.window(web.window_handles[0])
print(web.find_element_by_xpath('//*[@id="s_position_list"]/ul/li[1]/div[1]/div[1]/div[1]/a/h3').text)


# 6、如果页面中遇到了 iframe如何处理
web.get("https://www.91kanju.com/vod-play/541-2-1.html")
# 处理iframe的话. 必须先拿到iframe. 然后切换视角到iframe . 再然后才可以拿数据
iframe = web.find_element_by_xpath('//*[@id="player_iframe"]')
web.switch_to.frame(iframe)  # 切换到iframe
# web.switch_to.default_content()  # 切换回原页面
tx = web.find_element_by_xpath('//*[@id="main"]/h3[1]').text
print(tx)

# 7、无头浏览器
from selenium.webdriver.chrome.options import Options
# 准备好参数配置
opt = Options()
opt.add_argument("--headless")
opt.add_argument("--disable-gpu")
web = Chrome(options=opt)  # 把参数配置设置到浏览器中
web.get("https://www.baidu.com")  # 此时不会弹出浏览器,静默操作

2、下拉框数据获取

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
import time

# 准备好参数配置
opt = Options()
opt.add_argument("--headless")
opt.add_argument("--disable-gpu")
web = Chrome(options=opt)  # 把参数配置设置到浏览器中
# web = Chrome()
web.get("https://www.endata.com.cn/BoxOffice/BO/Year/index.html")

time.sleep(2)
# 定位到下拉列表
sel_el = web.find_element(By.XPATH, '//*[@id="OptionDate"]')
# 对元素进行包装, 包装成下拉菜单
sel = Select(sel_el)
# 让浏览器进行调整选项
for i in range(len(sel.options)):  # i就是每一个下拉框选项的索引位置
    sel.select_by_index(i)  # 按照索引进行切换
    time.sleep(2)
    table = web.find_element(By.XPATH, '//*[@id="TableList"]/table')
    print(table.text)  # 打印所有文本信息
    print("===================================")

print("运行完毕.  ")
web.close()


# 如何拿到页面代码Elements(经过数据加载以及js执行之后的结果的html内容)
# print(web.page_source)

3、登录验证码识别

chaojiying.py

#!/usr/bin/env python
# coding:utf-8

import requests
from hashlib import md5


class Chaojiying_Client(object):

    def __init__(self, username, password, soft_id):
        self.username = username
        password = password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def PostPic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                          headers=self.headers)
        return r.json()

    def ReportError(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()


if __name__ == '__main__':
    # 用户中心>>软件ID 生成一个替换 96001
    chaojiying = Chaojiying_Client('账号', '密码', '验证码')
    # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    im = open('a.jpg', 'rb').read()
    # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()
    print(chaojiying.PostPic(im, 1902))
from selenium.webdriver import Chrome
from chaojiying import Chaojiying_Client
from selenium.webdriver.common.by import By
import time

web = Chrome()

web.get("http://www.chaojiying.com/user/login/")

# 处理验证码
img = web.find_element(By.XPATH, '/html/body/div[3]/div/div[3]/div[1]/form/div/img').screenshot_as_png
chaojiying = Chaojiying_Client('账号', '密码', '验证码')
dic = chaojiying.PostPic(img, 1902)
verify_code = dic.get("pic_str")
# verify_code = dic['pic_str']

# 向页面中填入用户名, 密码, 验证码
web.find_element(By.XPATH, '/html/body/div[3]/div/div[3]/div[1]/form/p[1]/input').send_keys("账号")
web.find_element(By.XPATH, '/html/body/div[3]/div/div[3]/div[1]/form/p[2]/input').send_keys("密码")
web.find_element(By.XPATH, '/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input').send_keys(verify_code)

time.sleep(2)
# 点击登录
web.find_element(By.XPATH, '/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input').click()

time.sleep(500)

猜你喜欢

转载自blog.csdn.net/weixin_39855998/article/details/122846715