爬虫入门总结

1、普通网页(无js动态加载)——lxml+requests

例子:爬取金庸小说全集

#全部金庸小说
# 导入模块
import requests
from lxml import html
import re
import os.path
#第一层  所有的金庸小说
starturl = 'http://www.jinyongwang.com/book/' #初始URL   记录所有金庸小说的名字
#//*[@id="main"]/div[2]/h2[1]/span
fpsection = None
page = requests.get(starturl, timeout=600)  # 请求网页数据
page.encoding='utf-8'
#print(page.encoding)
#print(page.text)
if page.status_code == requests.codes.ok:   # 如果网页传输正常
    m = [] #具体章节内容所在网页链接
    n=[] #章节标题
    tree = html.fromstring(page.text)  # 将网页解析为一个树状结构
    author=tree.xpath('//*[@id="main"]/div[2]/h2[1]/span/text()')
    dir = 'D:\data\\' +author[0]+'\\'
    if not os.path.exists(dir):
        os.mkdir(dir)  # 新建以金庸命名的文件夹
    bookName = tree.xpath('//*[@id = "main"]/div[2]/ul[1]')#查找每本书的名字
    #//*[@id = "main"]/div[2]/ul[1]/li[1]/p[1]/a/img/@alt
    #//*[@id="main"]/div[2]/ul[1]/li[2]/p[1]/a/img
    u = bookName[0]  # 定位到其中的第一个节点
    for na in u.xpath('./li'):  # 定位子节点
        name=na.xpath('./p[1]/a/img/@alt')#分出每本书的名字
        print(name)
        bookhref=na.xpath('./p[1]/a/@href')#分出每本书的链接
        path = dir+name[0] + '\\'  # 文件存放目录(目录必须以\\结尾)
        print(path)
        if not os.path.exists(path):
            os.mkdir(path)  # 新建以小说命名的文件夹
        #第二层   每本书
        bookurl='http://www.jinyongwang.com'+bookhref[0]#每本书目录网页地址
        print(bookurl)
        listpage = requests.get(bookurl, timeout=600)  # 请求网页数据
        if listpage.status_code == requests.codes.ok:  # 如果网页传输正常
            listtree = html.fromstring(listpage.text)  # 将网页解析为一个树状结构
            elem = listtree.xpath('//*[@id="pu_box"]/div[3]/ul') #在树中导航,找到对应的节点列表--进入每章内容
            ul = elem[0]  #定位到其中的第一个节点
            for li in ul.xpath('./li'):  #定位子节点
                href = li.xpath('./a/@href')#具体章节内容1链接
                ctitle=li.xpath('./a/text()')#章节名
                if ctitle:
                    fpsection = open(path + ctitle[0] + '.txt', 'w',encoding = 'utf-8')#小心编码问题
                    n.append(''.join(ctitle))
                if href:
                    m.append(''.join(href))
                    #第三层    爬取章节内容
                    url='http://www.jinyongwang.com'+href[0]
                    print(url)
                    childpage = requests.get(url, timeout=600)  # 请求网页数据
                    childpage.encoding = 'utf-8'
                    childtree = html.fromstring(childpage.text)  # 将网页解析为一个树状结构
                    #进入章节列表,记录章节信息
                    childelem = childtree.xpath('//*[@id="vcon"]')  # 在树中导航,找到对应的节点列表
                    for txt in childelem[0].xpath('./p'):
                        content=txt.xpath('./text()')
                        for child in content:
                            fpsection.write('   '+child+'\n')
                if fpsection:
                    fpsection.close()
            #print(m)#所有章节链接
            #print(n)#所有标题

2、有js动态加载网页(查看源代码看不到,但开发者工具元素定位能看到)——selenium

注意:selenium webdriver加载动态网页需要时间,因此请求之后一定要停顿几秒,否则请求到的网页依然没有动态信息

lxml和selenium可以混合使用,例子如下(爬取沪深股票信息存入Excel):
#http://quote.hexun.com/default.htm#stock
#http://stockdata.stock.hexun.com/600268.shtml
#http://stockdata.stock.hexun.com/300153.shtml
from lxml import html
import time
import xlwt
from selenium import webdriver
wb = xlwt.Workbook()  # 创建xls文件对象
sh = wb.add_sheet('沪深股票信息')  # 新增一个表单

driver = webdriver.Chrome()
driver.get("http://quote.hexun.com/stock/stock.aspx?type=2&market=0")
time.sleep(3)#等待js加载完毕
# driver.switch_to_frame("ifrName")#切换到框架——适合有页面框架的情况,看网页结构
# print(driver.page_source)
tree = html.fromstring(driver.page_source)
#/table/tbody/tr[1]/td[1]/a
#http://quote.hexun.com/stock/stock.aspx?type=2&market=0
#http://quote.hexun.com/stock/stock.aspx?type=2&market=0
#
#//*[@id="StockListPage"]/table/tbody/tr[3]/td[1]/a
lists=tree.xpath('//*[@id="StockListPage"]/table/tbody')
if lists:
    list=lists[0]
    r = 0
    # 表格初始化
    sh.write(0, 0, '代码')
    sh.write(0, 1, '名称')
    sh.write(0, 2, '最新价')
    sh.write(0, 3, '涨跌幅')
    sh.write(0, 4, '昨收')
    sh.write(0, 5, '今开')
    sh.write(0, 6, '最高')
    sh.write(0, 7, '最低')
    sh.write(0, 8, '成交量')
    sh.write(0, 9, '成交额')
    sh.write(0, 10, '换手')
    sh.write(0, 11, '振幅')
    sh.write(0, 12, '量比')
    sh.write(0, 13, '所属地区')
    sh.write(0, 14, '总股本(亿)')
    sh.write(0, 15, '每股收益')
    sh.write(0, 16, '净资产收益率(%)')
    sh.write(0, 17, '流通A股(亿)')
    sh.write(0, 18, '主营收入增长(%)')
    sh.write(0, 19, '所属行业')

    for em in list.xpath('./tr'):
        name = em.xpath('./td[2]/a/text()')  # 名称
        if name:  # 第一行字段名称有的有链接,有的没有,字段不太同意,这里跳过,手动在Excel中写
            r = r + 1
            # //*[@id="StockListPage"]/table/tbody/tr[9]/td[1]/a
            id = em.xpath('./td[1]/a/text()')  # 代码
            print(id)
            sh.write(r, 0, id)

            print(name)
            sh.write(r, 1, name)
            # //*[@id="StockListPage"]/table/tbody/tr[9]/td[3]/span
            newPrice = em.xpath('./td[3]/span/text()')  # 最新价
            print(newPrice)
            sh.write(r, 2, newPrice)
            zdDgree = em.xpath('./td[4]/span/text()')  # 涨跌幅
            print(zdDgree)
            sh.write(r, 3, zdDgree)
            # //*[@id="StockListPage"]/table/tbody/tr[2]/td[5]
            yesterday = em.xpath('./td[5]/text()')  # 昨收
            print(yesterday)
            sh.write(r, 4, yesterday)
            today = em.xpath('./td[6]/span/text()')  # 今开
            print(today)
            sh.write(r, 5, today)
            highest = em.xpath('./td[7]/span/text()')  # 最高
            print(highest)
            sh.write(r, 6, highest)
            # //*[@id="HK1"]/table/tbody/tr[8]/td[8]——部分有差异
            lowest = em.xpath('./td[8]/text()')  # 最低
            if not lowest:
                lowest = em.xpath('./td[8]/span/text()')  # 最低
            sh.write(r, 7, lowest)
            sales = em.xpath('./td[9]/text()')  # 成交量
            print(sales)
            sh.write(r, 8, sales)
            amount = em.xpath('./td[10]/text()')  # 成交额
            print(amount)
            sh.write(r, 9, amount)
            hand = em.xpath('./td[11]/text()')  # 换手
            print(hand)
            sh.write(r, 10, hand)
            zf = em.xpath('./td[12]/text()')  # 振幅
            print(zf)
            sh.write(r, 11, zf)
            rate = em.xpath('./td[13]/text()')  # 量比
            print(rate)
            sh.write(r, 12, rate)
            # 处理详细页
            //*[@id="chapter-95998407"]/div/div[2]
            //*[@id="chapter-95998407"]/div
            /html/body/div[1]
            //*[@id="j_chapterBox"]
            //*[@id="chapter-95998407"]
            //*[@id="chapter-95998407"]/div
            
            if id:
                driver.get("http://stockdata.stock.hexun.com/" + id[0] + ".shtml")
                time.sleep(3)
                # print(driver.page_source)
                area = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[1]/td[2]/a').text  # 所属地区
                print(area)
                sh.write(r, 13, area)
                sum = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[3]/td[2]/a').text  # 总股本
                print(sum)
                sh.write(r, 14, sum)
                income = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[1]/td[4]').text  # 每股收益
                print(income)
                sh.write(r, 15, income)
                inRate = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[3]/td[4]').text  # 净资产收益率(%)
                print(inRate)
                sh.write(r, 16, inRate)
                A = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[4]/td[2]/a').text  # 流通A股(亿)
                print(A)
                sh.write(r, 17, A)
                increase = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[4]/td[4]').text  # 主营收入增长(%)
                print(increase)
                sh.write(r, 18, increase)
                pro = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[8]/td[2]/a').text  # 所属行业
                print(pro)
                sh.write(r, 19, pro)
else:
    print("列表为空!")
driver.close()
# 保存文件
wb.save("E:\Data\\"+'gupiao.xls')

3、对比总结

1)请求网页方式:

lxml:page = requests.get(starturl, timeout=600)  # 请求网页数据

selenium:driver.get(starturl)

2)获取网页源代码方式:

lxml:print(page.text)

selenium:print(driver.page_source)

3)元素定位方式:

lxml:newPrice = em.xpath('./td[3]/span/text()')  # 最新价

selenium:income = driver.find_element_by_xpath('//*[@id="list3"]/table/tbody/tr[1]/td[4]').text  # 每股收益

你可能感兴趣的:(爬虫入门总结)