Python网络爬虫(Xpath解析, lxml库, selenium)


安装:
  Windows :安装selenium
      python -m pip install selenium
  Anaconda Prompt下执行 : 
      conda install selenium
Linux/Mac OS:
      sudo pip3 install selenium

  Ubuntu :安装Scrapy框架
    #### 依赖库较多,以下为全部依赖库,有些已安装 ####
    sudo apt-get install libssl-dev
       sudo apt-get install libffi-dev 
       sudo apt-get install python3-dev
       sudo apt-get install build-essential
       sudo apt-get install libxml2
       sudo apt-get install libxml2-dev
       sudo apt-get install libxslt1-dev
       sudo apt-get install zlib1g-dev
    sudo pip3 install Scrapy


xpath工具(解析)
  xpath
    在XML文档中查找信息的语言,同样适用于HTML文档的检索
  xpath辅助工具
    Chrome插件 :XPath Helper
      打开 :Ctrl + Shift + X
      关闭 :Ctrl + Shift + X
    Firefox插件 :XPath checker
    XPath表达式编辑工具 :XML quire
  xpath匹配规则
    匹配演示
      查找bookstore下所有节点:/bookstore
      查找所有的book节点://book
      查找所有book下的title节点中,lang属性为"en"的节点
        //book/title[@lang="en"]
      查找bookstore下的第2个book节点下的title节点:
        /bookstore/book[2]/title/text()
    选取节点
      /  : 从根节点开始选取 
      // : 从整个文档中查找节点
           //price  、  /bookstore/book//price
      @  : 选取某个节点的属性
           //title[@lang="en"]
     @的使用
      选取1个节点 : //title[@lang="en"]
      选取N个节点 : //title[@lang]
      选取节点的属性值 : //title/@lang
<a class=....,src="http://..."
    匹配多路径
      符号 : |
      获取所有book节点下的 title节点和price节点
        //book/title | //book/price
    函数
      contains() : 匹配一个属性值中包含某些字符串的节点
      //title[contains(@lang,"e")]
      text() 
        //title[contains(@lang,"e")]/text()

lxml库及xpath使用
  lxml库 :HTML/XML解析库
    安装 

      python -m pip install lxml
      conda install lxml

    使用流程
      导模块
        from lxml import etree
      利用lxml库的etree模块创建解析对象
        parseHtml = etree.HTML(html)
      解析对象调用xpath工具定位节点信息
        r_list = parseHtml.xpath('xpath表达式')
### 只要调用了xpath,结果一定是列表 ###
# 构造解析对象
parseHtml = etree.HTML(html)
# 利用解析对象调用xpath匹配
r1 = parseHtml.xpath('//a/@href')
print(r1)

# 获取 /
r2 = parseHtml.xpath('//a[@id="channel"]/@href')
print(r2)

# 获取非 /
r3 = parseHtml.xpath('//ul[@id="nav"]//a/@href')
print(r3)
# 获取所有 a 节点的文本内容
r4 = parseHtml.xpath('//a/text()')
print(r4)
# 获取 图片、军事 ... 
r5 = parseHtml.xpath('//ul[@id="nav"]//a')
for i in r5:
    print(i.text)


    如何获取节点对象的内容
      节点对象.text
抓取百度贴吧帖子里面所有的图片
      目标 :抓取指定贴吧所有图片
      思路
        获取贴吧主页URL,下一页:找URL规律
获取1页中每个帖子的URL
对每个帖子URL发请求,获取帖子里图片URL
对图片URL发请求,以wb方式写入本地文件
      步骤
        获取贴吧主页URL
  http://tieba.baidu.com/f? + 查询参数
找到页面中所有帖子的URL
Python网络爬虫(Xpath解析, lxml库, selenium)
  src : 完整链接
  href : 和主URL进行拼接
    /p/5926064184
            http://tieba.baidu.com/p/5926064184
  xpath匹配链接:
   写法1: //div[@class="col2_right j_threadlist_li_right"]/div/div/a/@href

           写法2(推荐): //div[@class="t_con cleafix"]/div/div/div/a/@href
找每个帖子中图片URL
  Xpath匹配:
    //img[@class="BDE_Image"]/@src

'''02_百度贴吧图片抓取案例.py'''
import requests
from lxml import etree
import time

class BaiduImageSpider:
    def __init__(self):
        self.headers = {"User-Agent":"Mozilla/5.0"}
        self.baseurl = "http://tieba.baidu.com"
        self.pageurl = "http://tieba.baidu.com/f?"
        
    # 获取所有帖子URL列表
    def getPageUrl(self,params):
        res = requests.get(self.pageurl,params=params,headers=self.headers) 
        res.encoding = "utf-8"
        html = res.text
        # 构建解析对象
        parseHtml = etree.HTML(html)
        # 帖子链接列表
        t_list = parseHtml.xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href')
        # t_list : ['/p/233432','/p/2039820',..]
        print(t_list)
        for t_link in t_list:
            # 拼接帖子完整链接
            t_link = self.baseurl + t_link
            self.getImageUrl(t_link)
    
    # 获取帖子中图片URL列表
    def getImageUrl(self,t_link):
        res = requests.get(t_link,headers=self.headers)
        res.encoding = "utf-8"
        html = res.text
        # 构造解析对象
        parseHtml = etree.HTML(html)
        img_list = parseHtml.xpath('//img[@class="BDE_Image"]/@src')
        print(img_list)
        for img_link in img_list:
            self.writeImage(img_link)
    
    # 保存到本地
    def writeImage(self,img_link):
        # 获取图片的bytes
        res = requests.get(img_link,headers=self.headers)
        res.encoding = "utf-8"
        html = res.content
        # filename
        filename = img_link[-12:]
        with open(filename,"wb") as f:
            f.write(html)
            time.sleep(0.5)
            print("%s下载成功" % filename)
    
    # 主函数
    def workOn(self):
        name = input("请输入贴吧名:")
        begin = int(input("请输入起始页:"))
        end = int(input("请输入终止页:"))
        
        for n in range(begin,end+1):
            pn = (n-1)*50
            params = {
                    "kw":name,
                    "pn":str(pn)
                }
            self.getPageUrl(params)
            
if __name__ == "__main__":
    spider = BaiduImageSpider()
    spider.workOn()

糗事百科-xpath
      目标 :用户昵称、段子内容、好笑数、评论数
      步骤
        找URL
  https://www.qiushibaike.com/8hr/page/1/
xpath匹配
  基准xpath://div[contains(@id,"qiushi_tag_")]

    用户昵称: ./div/a/h2
    段子内容: .//div[@class="content"]/span
    好笑数量: .//i
    评论数量: .//i
动态网站数据抓取
  Ajax动态加载
    特点 :滚动鼠标混轮时加载
    抓包工具 :查询参数在 WebForms -> QueryString


'''03_糗事百科案例.py'''
import requests
from lxml import etree
import pymongo

class QiuShiSpider:
    def __init__(self):
        self.url = "https://www.qiushibaike.com/8hr/page/1/"
        self.headers = {"User-Agent":"Mozilla/5.0"}
        self.conn = pymongo.MongoClient("localhost",27017)
        self.db = self.conn.Baikedb
        self.myset = self.db.baikeset
        
    def getPage(self):
        res = requests.get(self.url,headers=self.headers)
        res.encoding = "utf-8"
        html = res.text
        self.parsePage(html)
    
    def parsePage(self,html):
        parseHtml = etree.HTML(html)
        # 基准xpath,每个段子的列表
        base_list = parseHtml.xpath('//div[contains(@id,"qiushi_tag_")]')
        # 遍历每个段子的节点对象(base)
        for base in base_list:
            # 用户昵称
            username = base.xpath('./div/a/h2')
            if len(username) == 0:
                username = "匿名用户"
            else:
                username = username[0].text
            # 段子内容
            content = base.xpath('.//div[@class="content"]/span')[0].text
            # 好笑数量
            # [<element.好笑数量>,<eleme.评论>,<element...>]
            laughNum = base.xpath('.//i')[0].text 
            # 评论数量
            pingNum = base.xpath('.//i')[1].text
            
            d = {
                  "username":username.strip(),
                  "content":content.strip(),
                  "laughNum":laughNum.strip(),
                  "pingNum":pingNum.strip()
              }
            self.myset.insert(d)
            print("存入数据库成功")


if __name__ == "__main__":
    spider = QiuShiSpider()
    spider.getPage()















上一篇:Python网络爬虫(正则, 内涵段子,猫眼电影, 链家爬取)


下一篇:三星笔记本R428安装xp win7双系统,切换系统重启才能进入系统解决办法。