内容简介:返回格式re.findall(正则表达式, 原来的字符串, flags=0)
正则表达式
正则表达式的基本符号
-
点号 "." 代替除了
换行符
以外的任何一个字符 -
星号 "*" 表示前面的一个子表达式(普通字符/另一个或几个正则表达式符号
0
到无限次
-
问号 "?" 表示前面的子表达式
0
或1
次 -
反斜杠 "" 不单独使用
- 转义
- \n 换行符
- \t 制表符
- \ 普通反斜杠
- ' 单引号
- " 双引号
- \d 数字
- 小括号 () 把括号里的内容提取出来
使用正则表达式
findall
返回 所有
满足要求的字符串
格式
re.findall(正则表达式, 原来的字符串, flags=0)
结果是一个列表, 包含了所有匹配的结果.如果没有匹配到,就是空列表
import re content = "账号A密码:12345, 账号B密码:67890, 所有密码" password_list = re.findall(':(.*?),', content) print(password_list) account_password = re.findall("账号(.*?)密码:(.*?),", content) print(account_password) ==> ['12345', '67890'] [('A', '12345'), ('B', '67890')]
flags 参数一些辅助功能,例如忽略大小写,re.S 忽略换行符.
import re html_string = ''' 账号A密码是123 456, ''' password_no_flag = re.findall('密码是(.*?),', html_string) password_flag = re.findall('密码是(.*?),', html_string, re.S) print(password_no_flag) print(password_flag)
返回 第一个
满足要求的字符串
格式
re.search(正则表达式, 原来的字符串, flags=0)
结果是一个正则表达式的对象, 匹配不到就是 None. 如果需要得到匹配的结果, 通过 .group() 获取值
import re content = "账号A密码:12345, 账号B密码:67890, 所有密码" password_search = re.search("账号(.*?)密码:(.*?),", content) print(password_search) print(password_search.group()) print(password_search.group(0)) print(password_search.group(1)) # 对应上面第一个括号 print(password_search.group(2)) # 对应上面第二个括号
贪婪匹配
获得最短的能满足条件的表达式
括号内可以有其他字符, 比如 (20178*?)
python 文件操作
格式
with open('文件路径', '文件操作方式', encoding='utf-8') as f: 对文件进行操作
使用 Python 读文件
文件路径是绝对路径, 也可以是相对路径. 但是不能使用 "~"家目录这种形式, 但是可以转化
import os real_path = os.path.expanduser('~/project/xxx')
读文件
with open('text.txt', encoding='utf-8') as f: content_list = f.readlines() # readlines 按照列表返回 print(content_list) with open('text.txt', encoding='utf-8') as f: content_str = f.read() # read 返回一个整体字符串 print(content_str)
使用 Python 写文件
with open("text.txt", "w", encoding="utf-8") as f: # w 新生成一个文件, wa 追加一个文件 f.write("你好") # 写一大段字符串 f.write("\n") # 写到文本的文件不会自动换行 f.writelines(["第一\n", "第二"]) # 写入一个列表 f.write("\n") f.write("end")
使用 Python 读/写 csv 文件
写 csv 文件
可以把字典写成 csv 文件, 或者把包含字典的列表写成 csv 文件, 列名和字典的 key 一一对应
import csv data = [{"name": "user01", "age": 10}, {"name": "user02", "age": 20}, {"name": "user03", "age": 30}] with open("new.csv", "w", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=['name', 'age']) writer.writeheader() # 表头 writer.writerows(data) # 数据 writer.writerow({"name": "user04", "age": 40})
读 csv 文件
第一种方法, 直接读
with open('new.csv', encoding="utf-8") as f: reader = csv.DictReader(f) for row in reader: print(row) # 这是个字典
第二种发放,利用列表推导式
with open('new.csv', encoding="utf-8") as f: reader = [x for x in csv.DictReader(f)] for row in reader: print(row)
Python 获取源代码
requests
GET
import requests html = requests.get("https://baidu.com").content.decode() print(html)
POST
import requests data = {'k1': 'v1', 'k2': 'v2'} html_formdata = requsts.post("url", data=data).content.decode() html_formdata = requsts.post("url", json=data).content.decode() # requests 自动将字典转 json
结合正则
title = re.search('title>(.*?)<', html, re.S).group(1) # 提取标题 content_list = re.findall("p>(.*?)<", html, re.S) # 提取正文 content_str = '\n'.join(content_list) # 用换行符拼起来
多线程爬虫
多线程
from multiprocessing.dummy import Pool def calc_power2(num): return num*num pool = Pool(3) # Pool 实现线程池 origin_num = [x for x in range(10)] result = pool.map(calc_power2, origin_num) print(f"{result}") => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
小说爬虫例子
import requests import re import os from multiprocessing.dummy import Pool url_start = "http://www.kanunu8.com/book3/6879/" html_start = requests.get(url_start).content.decode("GBK") toc_block = re.findall("正文(.*?)</tbody>", html_start, re.S)[0] toc_url = re.findall('href="(.*?)"', toc_block, re.S) toc_url_list = [] for url in toc_url: toc_url_list.append(url_start + url) print(toc_url_list) os.makedirs("动物农场", exist_ok=True) def get_doc_content(url): print(url) chapter_html = requests.get(url).content.decode("GBK") chapter_name = re.search('size="4">(.*?)<', chapter_html, re.S).group(1) text_block = re.search('<p>(.*?)</p>', chapter_html, re.S).group(1) text_block = text_block.replace('<br />', '') with open(os.path.join("动物农场", chapter_name + '.txt'), 'w', encoding="utf-8") as f: f.write(text_block) pool = Pool(8) result = pool.map(get_doc_content, toc_url_list)
html 内容解析
pip install lxml
返回一个 列表
语法
- 获取文本 //标签1[@属性1="属性值1"]/标签2[@属性2="属性值2"]/.../text()
- 获取属性值 //标签1[@属性1="属性值1"]/标签2[@属性2="属性值2"]/.../@属性n # a/@href
- 以相同的字符串开头 //标签[starts-with(@属性名, "相同的开头部分")] # //div[starts-with(@id, "test")]/text()
- 属性值包含相同字符串 //标签[starts-with(@属性名, "包含的字符串")]
- 对 xpath 返回的对象再次执行 xpath , 子 xpath 开头不需要添加斜线, 直接标签
- 使用 string(.) 提取文本
import lxml.html selector = lxml.html.fromstring(html) info = selector.xpath('xpath 语句') info_list = info[0].xpath(ul/li/text()) info_string = info.xpath('string(.)')
Beautifull Soup4
pip install beautifullsoup4 from bs4 import BeautifullSoup
解析源代码
soup = BeautifulSoup("网页源代码", "解析器") soup = BeautifulSoup("网页源代码", 'html.parser') # 两种解析器 soup = BeautifulSoup("网页源代码", "lxml") from bs4 import BeautifullSoup info = soup.find(class_="test") all_content = info.find_all('li') for li in all_content: print(li.string) # 通过 string 读出文本信息
find() 与 find_all() 参数相同
find(name, attrs, recursive, text, **kwargs)
- name html 的标签名, body, div, ul, li
- attrs 一个字典, key 是属性名, value是属性值 attrs={'class': 'usefull'}
- recursive 的值为 True 或 False. 当为 False , BS4 不会搜索子标签
- text 可以是一个字符串或正则表达式, 用户搜索标签里的文本信息
content = soup.find_all(text=re.compile('文本信息')) for each in content: print(each.string)
- **kwarg 表示 k=v 形式的参数. k 是属性, v 是属性值. 有时候属性非常特殊, 可以省略标签
find_all('div', id='test') find_all(class_='iamstrange') content = soup.find_all(re.compile('iam')) # 支持正则匹配 for each in content: print(each.string)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 爬虫入门到精通-网页的下载
- php 网站爬虫入门 - Goutte
- Python爬虫天气预报(小白入门)
- Python爬虫天气预报(小白入门)
- 爬虫入门之scrapy模拟登陆(十四)
- 简洁全面的Scrapy爬虫技术入门
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。