解析库

一、正则表达式

    规则
        单字符:
            . : 除换行以外所有字符
            []: 里面内容中的任意一个 [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



你可能感兴趣的:(解析库)