一、正则表达式
规则
单字符:
. : 除换行以外所有字符
[]: 里面内容中的任意一个 [aoe] [a-w]
\d: 数字[0-9]
\D: 非数字
\w: 数字、字母、下划线、中文
\W: 非\w
\s: 所有的空白字符
\S: 非空白
数量修饰
*: 任意多次 >=0
+: 至少一次
?: 可有可无 0次或一次
{m}:固定m次
{m, }:至少m次
{m, n}: m-n次
边界:
\b \B
$: 以某某结尾
^: 以某某开头
分组:
()视为一个整体 (ab){3}
() 子模式\组模式 \1 \2
贪婪模式
.*? .+?
re.I:忽略大小写
re.M:多行匹配
re.S:单行匹配
match\search\findall
re.sub(正则表达式,替换内容,字符串)
pattern(替换内容,字符串)
二、xpath
from lxml import etree
# xpath是一种语法,可以在xml文件中根据文档结构提取出目标内容(html是一种xml)
# lxml库用于分析和提取xml文件中的内容,etree是lxml里面的一个工具,用于把一个xml文件解析成
# 一个树形结构(层级结构)
# 1.用etree把整个html字符串加载出来,生成一棵节点树
html_tree = etree.parse("./test.html")
print(html_tree)
# 2.根据树型结构获取目标节点
ret = html_tree.xpath("/html/body/div/ol[1]/li/text()")
ret = html_tree.xpath("/html/body/div/div[2]/a/@href") # xpath语法中节点属性要用@符号来修饰
# 找节点中的内容与属性
# 3.定位
# 层级定位 "/"代表节点前面有一层 "//"代表有若干层
ret = html_tree.xpath("//li/text()")
# 属性定位
# 获取页面中class属性的li
ret = html_tree.xpath("//li[@class]")
# 获取所有的class值为hehe的li
ret = html_tree.xpath('//li[@class="haha pp"]')
ret = html_tree.xpath('//li[@class="haha pp"]') # 如果一个节点的某个属性有多个值一定要把这些值写全
# 模糊匹配
# 所有class值以h开头的li
ret = html_tree.xpath('//li[starts-with(@class, "h")]')
# 所有class值中含有a的li
ret = html_tree.xpath('//li[contains(@class, "a")]')
# ret = html_tree.xpath('//li[ends-with(@class, "a")]') # 匹配结尾的函数有的版本已经废弃
# 逻辑运算
# 查找所有class值为hehe并且id值为tata的li
ret = html_tree.xpath("//li[@class='hehe' and @id='tata']")
# 查找所有的class值为hehe或者含有a1的
ret = html_tree.xpath("//li[@class='hehe' or contains(@class, 'a')]")
obj = html_tree.xpath("//div[@id='pp']")[0]
print(obj)
# 以obj为根,继续向内部查找
# ret = obj.xpath('//li/text()') # 无论以谁为根,只要以//开头都以html为根
ret = obj.xpath(".//li/text()")
# print(ret)
三、bs4
from bs4 import BeautifulSoup
# 把html字符串初始化成一个BeautifulSoup对象
soup = BeautifulSoup(open("./soup_test.html", encoding='utf-8'), "lxml")
# 参数1,一个html字符串 参数2,是一个解析器(bs4没有自己的解析器,如果加入其它的解析器,可以提高其解析效率)
# print(soup)
# 1.根据标签名来查找对象,这种方法返回的是这类标签中的第一个
# print(soup.title)
# print(soup.li)
# 2.获取标签中的内容
obj = soup.a
# print(obj.string) # 获取页面中字符串(包括被注释掉的那些),string属性如果有多个子节点,无法获取
print(obj.get_text()) # 获取当前标签中的字符串(包括所有的后代标签中的字符串,无法获取注释的内容)
# 3.获取属性
print(obj.get("href")) # 用get方法获取
print(obj["href"]) # 用字典键值获取
print(obj.attrs) # 获取标签的所有属性(得到一个字典)
print(obj.name) # 获取标签元素名
# 获取子节点
# print(soup.body.children)
# for child in soup.body.children:
# print(child)
# 获取当前节点的所有后代节点
# print(soup.body.descendants)
# for i in soup.body.descendants:
# print(i)
# 4.根据相关函数来查找节点
# find函数,返回一个对象
# print(soup.find("a")) # 寻找第一个a标签
# print(soup.find("a", id='hong'))
# find_all函数返回一个别表
# print(soup.find_all("a"))
# print(soup.find_all(["a", "span", "li"]))
# print(soup.find_all(["a", "span", "li"], class_='taohua'))
# print(soup.find_all(["a", "span", "li"], limit=3))
# select函数,根据css选择器来查找
print(soup.select(".tang ul li")) # 派生选择器
print(soup.select("li#hong")) # 组合
print(soup.select("[name='he']")) # 属性选择器
四、存储数据
# 存储数据
# 存入json
def write_to_json(data):
# 把数据整合json支持的类型
json_list = []
for houses in data:
for house in houses:
json_list.append(house)
with open("lianjie.json", "w", encoding="utf-8") as fp:
fp.write(json.dumps(json_list))
# 存入csv
def write_to_csv(data):
# 在写csv的时候,首先需要把data整合一个二维列表
items = []
for houses in data:
for house in houses:
item = []
# house是字典,按照键值的形式存储了每个房屋的信息. 写入一个列表
for v in house.values():
item.append(v)
items.append(item)
# 写入csv
with open("lianjia.csv", "w") as fp:
# 用fp来创建一个csv的写对象
w = csv.writer(fp)
# 写表头
w.writerow(["title", "house", "position", "totalPrice", "unitPrice", "img"])
# 写数据
w.writerows(items)
# 存入mysql
def write_to_mysql(data):
# 创建一个mysql数据库的链接
conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", password="qaz1693146287", db="lianjia", charset="utf8")
# 创建一个游标,用于解析sql语句
cursor = conn.cursor()
conn.begin()
# 创建sql语句
for houses in data:
for house in houses:
sql = 'insert into lianjia values(null, "%s", "%s", "%s", "%s", "%s", "%s")' % (house.get("title"), house.get("house"), house.get("position"), house.get("totalPrice"), house.get("unitPrice"), house.get("img"))
cursor.execute(sql)
conn.commit()
# 关闭游标和数据库
cursor.close()
conn.close()
五、selenium
selenium+phatomjs和selenium+chrome
selenium:是一种用于web程序测试的工具,selenium测试的代码可以直接运行在浏览器中,就像真正的用户操作一样。
在写python爬虫的时候,主要是用selenium的webdriver 来驱动浏览器进行相关的操作
安装:pip install selenium
selenium中元素查找:
find_element_by_id()
find_elements_by_name()
find_elements_by_xpath()
find_elements_by_tag_name()
find_elements_by_class_name()
find_elements_by_css_selector()
find_elements_by_link_text()
事件
click() 点击
send_keys()
switch_to_alert()
聚焦到iframe
driver.switch_to.frame(driver.find_element_by_id("login_frame"))
获取网页内容
driver.page_source
chromedriver:谷歌浏览器驱动
加载方法如下:
法一:driver = webdriver.Chrome(r'/Users/fanjianbo/Desktop/chromedriver')
法二:把chromedriver的目录配成环境变量路径,然后:driver = webdriver.Chrome()
【注意】chromedriver的版本要和chrome浏览器相对应,不然很多功能不能用
下载操作谷歌浏览器驱动的页面:http://chromedriver.storage.googleapis.com/index.html 或者 http://npm.taobao.org/mirrors/chromedriver/2.37/
谷歌驱动和谷歌浏览器版本之间的映射表:http://blog.csdn.net/huilan_same/article/details/51896672
phantomjs:无界面浏览器
加载方法如下:
法一:driver = webdriver.PhatomJS("C:\Users\ZBLi\Desktop\1706\day04\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe")
法二:把phantomjs拷贝到c盘下,并把bin目录配置成环境变量,然后driver = webdriver.PhatomJS()
【注意】phantomjs目前已经不再更新
下载地址:http://phantomjs.org/download.html