python爬虫学习

该文章仅是学习后的自我总结,方便后续查看

文章目录

(一)requests库

1.第一个简单的爬虫语句

import requests
r=requests.get("http://www.baidu.com/")
r.status_code   #查看状态码,如果200则正常
r.encoding='utf-8'  
print(r.text)

2.获得的网页内容的一些属性

r.encoding:从HTTP header中猜测的响应内容编码方式
r.apparent_encoding:从内容中分析出的响应内容编码方式(备选编码方式)
r.content:响应内容的二进制形式(比如图片)
r.headers #获取头部信息
r.raise_for_status() #如果状态不是200,则会引发HTTPError异常
r.request.url:查看服务器发送请求的网页
r.request.headers:查看服务器发送请求的headers

3.爬取网页的通用框架

import requests
def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)  
        r.raise_for_status()  #如果状态不是200,则会引发HTTPError异常
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return "产生异常"
if __name__=="__main__":
    url="http://www.baidu.com"
    print(getHTMLText(url))

4.requests的timeout参数

  • timeout参数其实就是为了防止你的程序运行进入无限的等待,如果想永久等待,可以将timeout的参数值设为None或者不设置该参数。
  • 在timeout 时间内,如果请求的内容还没返回去,它将产生timeout异常
  • timeout参数可以传入一个简单的浮点数,它将请求的连接部分和读取部分设为相同的超时时间。
  • timeout参数也可以传入一个包含两个简单浮点数的元组,用来分别设置请求连接超时时间和读取超时时间。
#这里设置超时时间为1,即连接和读取时间都为1秒
r=requests.get("http://gethub.com",timeout=1)
print(r.status_code)

#执行结果会报错:因为连接时间超时了
ConnectTimeout: HTTPConnectionPool(host='gethub.com', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x000001A0AACD1128>, 'Connection to gethub.com timed out. (connect timeout=1)'))
#这里设置timeout为一元组,连接时间和读取时间分别为2秒和0.01秒
r = requests.get("https://baidu.com", timeout=(2, 0.01))
print(r.status_code)

#执行结果会报错:读取超时了
 HTTPSConnectionPool(host='baidu.com', port=443): Read timed out. (read timeout=0.01)

5. requests库方法

在这里插入图片描述
在这里插入图片描述

#向url post一个字典,自动编码为form表单
payload={'key1':'value1','key2':'value2'}
r=requests.post('http://httpbin.org/post',data=payload)
print(r.text)
#向url post一个字符串,自动编码为data
r=requests.post('http://httpbin.org/post',data='ABC')
print(r.text)
r=requests.head("http://httpbin.org/get")
print(r.headers)
print(r.text)  #代码结果为空

6. requests爬虫小案列

亚马逊商品页面的爬取

import requests
url="https://www.amazon.cn/gp/product/B01M8L5Z3Y"
kv={'user-agent':'Mozilla/5.0'} #模拟浏览器访问
try:
    r=requests.get(url,headers=kv)
    r.raise_for_status()
    r.encoding=r.apparent_encoding
    print(r.text[:1000])
except:
    print("爬取失败")

百度搜索关键词提交

百度的关键词接口:
http://www.baidu.com/s?wd=keyword
360的关键词接口:
http://www.so.com/s?q=keyword

import requests
url="http://www.baidu.com/s"
kv={'wd':'Python'}
try:
    r=requests.get(url,params=kv)
    r.raise_for_status()
    r.encoding=r.apparent_encoding
    print(r.text[:1000])
except:
    print("爬取失败")

网络图片的爬取和储存

import requests
url="http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
path="D:\pics.jpg"
try:
    r=requests.get(url)
    r.raise_for_status()
    with open(path,'wb') as f:
        f.write(r.content)
        f.close()
except:
    print("爬取失败")

(二)BeautifulSoup

1. BeautifulSoup类的基本元素

在这里插入图片描述

2.基于bs4库的HTML内容遍历方法

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

3.Prettify()

from bs4 import BeautifulSoup
import requests
url="http://python123.io/ws/demo.html"
r=requests.get(url)
demo=r.text
soup=BeautifulSoup(demo,'lxml')
print(soup.prettify()) #可以将soup按格式输出

4.基于bs4的HTML内容查找方法

<>.find_all(name,attrs,recursive,string,**kwargs)
返回一个列表类型,存储查找的结果
name:对标签名称的检索字符串
attrs:对标签属性值的检索字符串,可标注属性检索
recursive:是否对子孙全部检索,默认是True
string:<>…</>中字符串区域的检索字符串

soup.find_all('a')  #找到所有的a标签
soup.find_all(['a','b']) #找到所有的a和b标签
#如果要找到soup中的所有标签可以用如下方法:
for i in soup.find_all(True):
    print(i.name)
#找到所有以b开头的标签,用到正则表达式re
for tag in soup.find_all(re.compile('b')):   
    print(tag.name)
#找出名为p,且属性为course的标签
soup.find_all('p','course')
soup.find_all('p',attrs='course')
#找出属性id为link1的标签
soup.find_all(id='link1')
#如果只对a 标签的子标签进行检索,则结果为空
soup.find_all('a',recursive=False)
#对字符串为‘Basic Python’的字符串进行检索
soup.find_all(string='Basic Python')
#输出结果为:['Basic Python']

#找出所有字符串包含python的字符串
soup.find_all(string=re.compile('python')

在这里插入图片描述

(三)中国大学排名爬虫

import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return ""
def fillUnivList(ulist,html):
    soup=BeautifulSoup(html,"html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr,bs4.element.Tag):
            tds=tr.find_all('td')   #tds=tr('td')
            ulist.append([tds[0].string,tds[1].string,tds[4].string])
def printUnivList(ulist,num):
    tplt="{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","学校名称","总分",chr(12288)))
    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))
def main():
    uinfo=[]
    url="http://zuihaodaxue.cn/zuihaodaxuepaiming2016.html"
    html=getHTMLText(url)
    fillUnivList(uinfo,html)
    printUnivList(uinfo,20)
main()

这里解释一下printUnivList()函数的格式化输出
填充常跟对齐一起使用
^、<、>分别是居中、左对齐、右对齐,后面带宽度
:号后面带填充的字符,只能是一个字符,不指定的话默认是用空格填充
在这里插入图片描述
例如:

temp=[]
temp.append([1,"清华大学","10" ])
 
temp.append([2,"中国科学技术大学","10"])
 
temp.append([3,"复旦大学","10"])

for i in temp:
    print("{:^6}\t{:^10}\t{:^6}".format(i[0],i[1],i[2]))

上面这个例子的结果就对不齐,原因是当中文字符串长度没有达到指定字符串长度时,默认会采用西文空格代替,而西文空格和中文空格长度不同,故导致中英文混输时不对齐了
解决方案如下:
采用chr(12288)表示中文空格

temp=[]
temp.append([1,"清华大学","10" ])
 
temp.append([2,"中国科学技术大学","10"])
 
temp.append([3,"复旦大学","10"])

for i in temp:
    print("{0:^6}\t{1:{3}^10}\t{2:^6}".format(i[0],i[1],i[2],chr(12288)))
    

(四)正则表达式

1.正则表达式常用操作符

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.匹配IP地址的正则表达式

在这里插入图片描述
在这里插入图片描述

3.re库的主要功能函数

在这里插入图片描述

re.search()

re.search(pattern,string,flags=0)
在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
pattern:正则表达式的字符串或原生字符串表示
string:待匹配的字符串
flags:正则表达式使用时的控制标记
在这里插入图片描述

import re
match=re.search(r'[1-9]\d{5}','BIT 100081')
if match:
    print(match.group(0))  #后面会讲到match的方法

re.match()

re.match(pattern,string,flags=0)
从字符串的开始位置起匹配正则表达式,返回match对象
pattern:正则表达式的字符串或原生字符串表示
string:待匹配的字符串
flags:正则表达式使用时的控制标记

match=re.match(r'[1-9]\d{5}','100081 BIT')
if match:
    print(match.group(0))

re.findall()

re.findall(pattern,string,flags=0)
搜索字符串,以列表类型返回全部能匹配的子串
pattern:正则表达式的字符串或原生字符串表示
string:待匹配的字符串
flags:正则表达式使用时的控制标记

ls=re.findall(r'[1-9]\d{5}','BIT100081 TSU100084')
print(ls)
#结果为:['100081', '100084']

re.split()

re.split(pattern,string,maxsplit=0,flags=0)
将一个字符串按照正则表达式匹配结果进行分割返回列表类型
pattern:正则表达式的字符串或原生字符串表示
string:待匹配的字符串
flags:正则表达式使用时的控制标记
maxsplit:最大分割数,剩下部分作为最后一个元素输出

re.split(r'[1-9]\d{5}','BIT100081 TSU100084')
#结果为:['BIT', ' TSU', '']

import re
re.split(r'[1-9]\d{5}','BIT100081 TSU100084',maxsplit=1)
#结果为:['BIT', ' TSU100084']

re.finditer()

re.finditer(pattern,string,flags=0)
搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
pattern:正则表达式的字符串或原生字符串表示
string:待匹配的字符串
flags:正则表达式使用时的控制标记

for m in re.finditer(r'[1-9]\d{5}','BIT100081 TSU100084'):
    if m:
        print(m.group(0))

re.sub()

re.sub(pattern,repl,string,count=0,flags=0)
在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串
pattern:正则表达式的字符串或原生字符串表示
repl:替换匹配字符串的字符串
string:待匹配的字符串
count:匹配的最大替换次数
flags:正则表达式使用时的控制标记

re.sub(r'[1-9]\d{5}',':zipcode','BIT100081 TSU100084')
#结果为:'BIT:zipcode TSU:zipcode'

4.re库的另一种等价用法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.re库的Match对象

match对象是一次匹配的结果,包含匹配的很多信息

Match对象的属性

在这里插入图片描述

Match对象的方法

在这里插入图片描述
这里我们从例子中讲一下group

import re
a = "123abc456"
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0))   #123abc456,返回整体,同group()
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1))   #123
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2))   #abc
print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3))   #456
#group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。

5.re库的贪婪匹配和最小匹配

match=re.search(r'PY.*N','PYANBNCNDN')
match.group(0)  
#输出结果为:'PYANBNCNDN'
#re库默认采用贪婪匹配,即输出匹配最长的子串
match=re.search(r'PY.*?N','PYANBNCNDN')
match.group(0)
#输出结果为:'PYAN'

在这里插入图片描述

(五) 淘宝商品信息定向爬虫

以下程序爬取淘宝“书包”产品的两页信息,由于淘宝网的robots.txt对所有用户爬取都有限制,所以我们就不要无限制的去爬取啦。


import requests
import re

def getHTMLText(url):
    try:
        headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
                "cookie": "输入自己的cookie"}  #这里为了保护隐私就不展示了
        r=requests.get(url,timeout=30,headers=headers)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text 
    except:
        return ""
def parsePage(ilt,html):
    try:
        plt=re.findall(r'\"view_price\"\:\"[\d\.]*\"',html)
        tlt=re.findall(r'\"raw_title\"\:\".*?\"',html)
        for i in range(len(plt)):
            price=eval(plt[i].split(':')[1])
            title=eval(tlt[i].split(':')[1])
            ilt.append([price,title])
    except:
        print("")
def printGoodsList(ilt):
    tplt="{:4}\t{:8}\t{:16}"
    print(tplt.format("序号","价格","商品名称"))
    count=0
    for g in ilt:
        count=count+1
        print(tplt.format(count,g[0],g[1]))
def main():
    goods="书包"
    depth=2
    start_url='https://s.taobao.com/search?q='+goods
    infoList=[]
    for i in range(depth):
        try:
            url=start_url+'&s='+str(44*i)
            html=getHTMLText(url)
            parsePage(infoList,html)
        except:
            continue
    printGoodsList(infoList)      
main()

#输出结果为:
序号  	价格      	商品名称            
   1	79.90   	书包女大学生韩版原宿ulzzang高中初中生电
   2	29.90   	双肩包男士大容量旅行包电脑背包2020年新款初中学生书包女小学生
   3	149.00  	鳄鱼男士双肩包商务休闲电脑帆布背包旅游旅行包时尚潮流学生书包
   4	35.00   	YOHOO! /仙仙的~chic韩系花朵泫雅风百搭单肩帆布包大学生书包女
   5	69.90   	YOHOO!/原创设计2019新款ins时尚书包旅行背包男女学生帆布双肩包
   6	9.90    	纯色空白手绘防水帆布包文艺女单肩环保手提袋学生书包定制logo
   7	49.80   	茶话会韩国ins书包女 大容量百搭学生双肩包chic可爱软妹少女背包
   8	38.80   	ins日系原宿街头机能工装斜挎包男港风复古单肩背包少女学生书包
   9	269.00  	CHARLES&KEITH女包CK2-80840173-1粗链条翻盖单肩情书包婚包
  10	99.00   	袋鼠双肩包男士大容量电脑商务书包女旅行大学生时尚潮流旅游背包
  11	318.00  	香港MICHONG真皮双肩包女士2020新款韩版背包休闲旅行大容量书包
  12	139.00  	瑞士军士刀双肩包男士大容量旅行电脑背包2020年新款初中学生书包
  13	169.00  	kk剑桥树儿童拉杆书包小学生男孩1-6年级拉杆箱书包男童防水爬楼
  14	119.00  	KK剑桥树书包小学生男孩一二三到六年级儿童6-12岁男童双肩包减负
  15	59.80   	儿童书包小学生男女一二三到六年级韩版减负护脊贵族书包轻便防水
  16	219.00  	七匹狼双肩包男士牛津纺布14寸电脑包商务休闲双肩包学生书包潮流
  17	249.00  	七匹狼双肩包男2020年夏季新款时尚潮流休闲大容量背包电脑包书包
  18	199.00  	瑞士军士刀双肩包男大容量休闲商务旅行电脑背包男士初中学生书包
  19	98.00   	迪士尼书包小学生女童1-3-6一三年级冰雪公主女孩轻便儿童双肩包8
  20	89.00   	迪士尼书包男小学生一二到三五六年级儿童双肩护脊减负轻便背包女
  21	169.00  	KK树小学生拉杆书包1-3-6年级女童6-12周岁儿童公主防水轻便背包
  22	68.80   	小学生拉杆书包女公主可拆卸两用1-3-6年级防水爬楼六轮男女背包
  23	188.00  	双肩儿童书包小学生男孩女童一二三到六年级轻便减负护脊3四五1-6
  24	136.00  	儿童奥特曼书包幼儿园 男童一年级1-3-8周岁卡通双肩包减负小背包
  25	139.00  	uek小学生书包男孩女生一二三四五六年级护脊双肩6-12岁轻便儿童
  26	138.00  	瑞士军刀双肩包男背包休闲商务旅行大容量瑞士书包高中生电脑男士
  27	59.00   	迪士尼书包小学生男童女童一二三到六年级四五超轻便减负儿童背包
  28	127.00  	七匹狼双肩包男2020新款书包大容量背包商务休闲男士旅行包电脑包
  29	69.00   	迪士尼儿童书包小学生男童1-36年级6-12岁漫威书包男孩双肩背包
  30	88.00   	迪士尼幼儿园书包男童蜘蛛侠美国队长小孩学前班宝宝儿童双肩背包
  31	69.00   	迪士尼超轻书包小学生轻便男童女童一二三年级六儿童护脊减负背包
  32	136.00  	泰罗奥特曼书包幼儿园儿童1-3-6岁男潮4宝宝可爱背包小孩卡通个性
  33	499.00  	日本进口卡芙露书包小学生1-3年级6儿童轻便减负护脊男女双肩背包
  34	299.00  	BOPAI博牌电脑背包男户外旅行休闲双肩包商务书包出差多功能男包
  35	69.00   	双肩包男士电脑背包大容量旅行高中初中学生书包女小学生时尚潮流
  36	129.00  	迪士尼小学生书包减负轻便儿童超轻1-3-4-6三到六年级护脊女男童5
  37	138.00  	迪士尼幼儿园书包女35可爱宝宝小班男女童儿童婴幼儿防走失背包
  38	198.00  	瑞士军刀双肩包男休闲大容量书包瑞士军士刀男士电脑商务旅行背包
  39	195.02  	国家地理背包女运动户外时尚双肩包男牛津布旅行防水学生情侣书包
  40	188.00  	优仅ALLJOINT儿童书包可爱幼儿园双肩甜甜圈彩虹幼儿背包女童包包
  41	78.00   	彬澳袋鼠韩版双肩背包男士商务休闲电脑包防水旅行包潮流学生书包
  42	49.00   	皮卡丘书包男时尚潮流儿童初中学生高中小学生双肩包大容量背包女
  43	89.00   	小学生拉杆书包男孩3-5-6年级儿童大容量防水可拖爬楼梯6-12周岁
  44	49.00   	男童书包小学生1-3-6年级女减负五儿童背包一二 三到六男孩四轻便
  45	69.00   	南极人小学生书包男孩女生一三五六年级护脊6-12岁轻便减压儿童包
  46	168.00  	迪士尼拉杆书包小学生3-5年级4男童6-12周岁男女儿童大号三轮男孩
  47	89.00   	巴布豆小学生书包女童孩一二年级减负护脊超轻679-12岁儿童背书包
  48	79.00   	巴布豆书包小学生1-3-4-6年级男女孩减负护脊背包儿童书包8-10-12
  49	89.00   	巴布豆小学生书包女童孩一二年级减负护脊超轻679-12岁儿童背书包
  50	79.00   	巴布豆书包小学生1-3-4-6年级男女孩减负护脊背包儿童书包8-10-12
  51	98.00   	迪士尼公主书包小学生1-3-6三四五年级韩版女生女童轻便儿童背包5
  52	399.00  	朱丹推荐诺狐书包小学生女孩一二三到六年级护脊减负儿童双肩背包
  53	399.00  	UNIKER初中学生拉杆书包可爬楼梯大轮子30升高中男女孩儿童拉杆包
  54	899.00  	[2020新款]挪威Beckmann小学生书包女男儿童护脊减压背包1-3年级
  55	133.00  	七匹狼双肩包男大容量男士旅游背包休闲商务旅行包超大电脑包书包
  56	69.00   	新款书包小学生女童一二三到六年级可爱儿童2019女孩韩版轻便减负
  57	229.00  	迪士尼商店 冰雪奇缘艾莎公主小学生书包儿童书包双肩包女童书包
  58	35.00   	YOHOO!/chic韩系慵懒风百搭款 单肩帆布袋手提大容量女学生书包包
  59	35.00   	YOHOO!/酷少女/年bi备大容量纯色百搭健身帆布包斜挎单肩书包男女
  60	59.80   	ins暗黑风工装双肩包女 大容量电脑旅行背包男学生复古港风书包潮
  61	37.50   	日系原宿风ins古着感书包女 两用暗黑风设计帆布包斜挎包学生包包
  62	129.00  	七匹狼双肩包男时尚背包大容量旅行旅游包潮流初中生高中学生书包
  63	129.00  	七匹狼男士商务休闲旅游双肩包学生大容量时尚简约休闲书包背包女
  64	108.00  	迪士尼小学生书包女童1-3-4三四年级冰雪奇缘女孩儿童减负双肩包6
  65	88.00   	凯蒂猫书包小学生女童一二三六年级女孩减负轻便儿童休闲双肩背包
  66	138.00  	儿童三轮六拉杆书包中小学生男孩1-3-4-5-6年级女防水箱可爬楼梯2
  67	399.00  	FILA斐乐童装旗舰店儿童双肩包小学生书包男童女童低年级背包新款
  68	59.00   	背包男士双肩包大容量电脑旅行时尚潮流大学生高中生初中学生书包
  69	69.00   	巴布豆小学生书包男孩1-3-4-6年级双肩护脊减负6-12周岁儿童书包
  70	127.00  	七匹狼双肩包男书包大学生女电脑包出差旅行男士初中生背包中学生
  71	219.00  	NIKE耐克双肩包男新款男包女包大容量运动包高中初中学生书包背包
  72	678.00  	正品代购蔻驰女包 coach新款双肩包小号背包时尚旅行包真皮书包
  73	139.00  	诺狐婴幼儿园书包女男宝宝1-3-6岁防走失背包儿童小书包韩版可爱
  74	88.00   	迪士尼书包小学生女三到六年级女童2020新款2019四五轻便儿童网红
  75	188.00  	牛津大学书包小学生男孩一二年级三到六儿童减负护脊轻便双肩女四
  76	239.00  	卡拉羊书包女1-3-4-6小学生网红减负护脊背包男防水校园学生书包
  77	98.00   	迪士尼书包小学生男孩1-3-4-6三到六年级潮男童美国队长儿童背包
  78	118.00  	瑞士军士刀双肩包男大容量休闲商务旅行电脑背包男士初中学生书包
  79	215.00  	Allen daniel日本小学生减负护脊书包1-3-4年级儿童双肩背包男女
  80	59.00   	巴布豆儿童书包小学生男一二三年级6-12岁女孩超轻便书包护脊减负
  81	339.00  	BOPAI博牌双肩包男商务休闲简约大容量背包时尚书包15.6寸电脑包
  82	149.00  	双肩包女2020年新款时尚韩版百搭牛津布简约2019旅行防盗背包书包
  83	1288.00 	英国Anything Studio小学生书包儿童英伦日本风进口超轻护脊HIPPO
  84	139.00  	花花公子男士双肩包时尚潮流休闲初中学生书包大学生电脑旅行背包
  85	59.00   	巴布豆旗舰店书包1-3年级护脊减负儿童书包男4-6小学生书包轻便
  86	378.00  	tigerfamily儿童书包小学生一年级1-3 女男6岁耐磨减负护脊双肩包
  87	285.00  	儿童节礼物unme小学生书包男女一二三到六年级儿童减负护脊双肩包
  88	79.00   	迪士尼儿童书包 小学生女1-3一年级冰雪奇缘爱莎公主双肩背包女童
  89	118.00  	瑞士军士刀双肩包男大容量休闲商务旅行电脑背包男士初中学生书包
  90	299.00  	UNIKER拉杆书包男孩大容量初中生女拉杆背两用小学6-12岁轻便书包
  91	218.00  	nike双肩背包男女包大容量运动包初高中学生耐克书包电脑背包605
  92	229.00  	朱尔防盗双肩包女2020新款时尚牛津布女士背包百搭书包帆布女包包

(六)利用python读取excel中的公司名称获取公司的经营范围并回填进excel中

1.使用BeautifulSoup解析

import requests
import pandas as pd
from pandas import Series
from bs4 import BeautifulSoup
def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return ""
    
def parsePage(html,scopeList):
    if html=="":
        scopeList.append("")
    else:
        soup=BeautifulSoup(html,'lxml')
        span=soup.find('span',attrs={'class':'zx-ent-item zx-ent-text expand'})
        r_s=span.attrs['data-content']
        scopeList.append(r_s)
def main():
    wb=pd.read_excel('C:\webshop_data\company.xlsx')
    c_names=wb['公司名称']
    c_names=list(c_names)
    scopeList=[]
    for i in range(len(c_names)):
        name=c_names[i]
        url="https://xin.baidu.com/s?q="+name
        html=getHTMLText(url)
        parsePage(html,scopeList)
    wb['经营范围']=Series(scopeList)
    wb.to_excel('company.xlsx')
main()

2.使用xpath解析

import pandas as pd
from lxml import etree
import requests
wb=pd.read_excel('C:\webshop_data\company.xlsx',index_col=0)
c_names=wb['公司名称']
scopeList=[]
for i in range(len(c_names)):
    name=c_names.iloc[i]
    url="https://xin.baidu.com/s?q="+name
    html=etree.HTML(requests.get(url).text)
    run_scope=html.xpath('/html/body/div[2]/div/div[2]/div[5]/div[1]/div/div[2]/div/div[1]/span[5]/@data-content')
    scopeList.append(run_scope[0])
wb['经营范围']=scopeList
wb.to_excel('company.xlsx')

(七)XPath的基本使用介绍

这部分参考:python爬虫之xpath的基本使用

1.etree.HTML()、etree.tostring()

etree.HTML():构造一个XPath解析对象并对HTML文本进行自动修正构造一个XPath解析对象并对HTML文本进行自动修正
etree.tostring():输出修正后的结果,类型是bytes

from lxml import etree
wb_data='''
<div>
    <ul>
        <li class="item-0"><a href="link1.html">first item</a></li>
        <li class="item-1"><a href="link2.html">second item</a></li>
        <li class="item-inactive"><a href="link3.html">third item</a></li>
        <li class="item-1"><a href="link4.html">fourth item</a></li>
        <li class="item-0"><a href="link5.html">fifth item</a>
    </ul>
</div>
'''
html=etree.HTML(wb_data)
print(html)
result=etree.tostring(html)
print(type(result))  #result的类型是bytes
lresult=result.decode("utf-8")  #decode()方法将其转化成str类型
print(lresult)
print(type(lresult))


#输出结果为:
<Element html at 0x1e72d152c48>
<class 'bytes'>
<html><body><div>
    <ul>
        <li class="item-0"><a href="link1.html">first item</a></li>
        <li class="item-1"><a href="link2.html">second item</a></li>
        <li class="item-inactive"><a href="link3.html">third item</a></li>
        <li class="item-1"><a href="link4.html">fourth item</a></li>
        <li class="item-0"><a href="link5.html">fifth item</a>
    </li></ul>
</div>
</body></html>
<class 'str'>

2.基本使用

- 获取a标签内容

方法一:
html_data=html.xpath('/html/body/div/ul/li/a')
print(html_data)
for i in html_data:
    print(i.text)
    
#输出结果:
[<Element a at 0x1e72d152408>, <Element a at 0x1e72d152388>, <Element a at 0x1e72d152088>, <Element a at 0x1e72d152808>, <Element a at 0x1e72d152dc8>]
first item
second item
third item
fourth item
fifth item


方法二:直接在需要查找内容的标签后面加一个/text()就行
html_data1=html.xpath('/html/body/div/ul/li/a/text()')
html_data1
#输出结果:
['first item', 'second item', 'third item', 'fourth item', 'fifth item']

- 打印指定路径下a标签的属性的值

html_data2=html.xpath('/html/body/div/ul/li/a/@href')
for i in html_data2:
    print(i)

#输出结果为:
link1.html
link2.html
link3.html
link4.html
link5.html

- a标签属性等于link2.html的内容

html_data3=html.xpath('/html/body/div/ul/li/a[@href="link2.html"]/text()')
print(html_data3)

#输出结果为:
['second item']

- 用相对路径查找所有li标签下的a标签内容

html_data3=html.xpath('//li/a/text()')
html_data3
#输出结果为:

['first item', 'second item', 'third item', 'fourth item', 'fifth item']

- 查找相对路径下li标签下的a标签下的href属性的值

html_data4=html.xpath('//li/a/@href')
html_data4
#输出结果为:
['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']

- 查找最后一个(或倒数第二个)li标签里的a标签的href文本

html_data6=html.xpath('//li[last()]/a/text()')
html_data6
#输出结果为:['fifth item']

html_data6=html.xpath('//li[last()-1]/a/text()')
html_data6
#输出结果为:['fourth item']

3. 如果在提取某个页面的某个标签的xpath路径的话

在这里插入图片描述

(七)获取股票历史数据(使用re,包含内容有json.loads,date.strftime)

1、获取股票历史数据

import requests
import re
import json
import pandas as pd
from datetime import date
def retrieve_quotes_historical(stock_code):
    url="https://finance.yahoo.com/quote/%s/history?p=%s"%(stock_code,stock_code)
    try:
        r=requests.get(url)
    except Exception as err:
        print(err)
    m=re.findall('"HistoricalPriceStore":{"prices":(.*?),"isPending"',r.text)
    if m:
        quotes=json.loads(m[0])  #json.load()函数是将字符串转化成字典
        quotes=quotes[::-1]  #将quotes倒序
        return [item for item in quotes if 'type' not in item]

quotes=retrieve_quotes_historical('AXP')
list1=[]
for i in range(len(quotes)):
    x=date.fromtimestamp(quotes[i]['date'])  #将date时间戳转换成常规时间
    y=date.strftime(x,'%Y-%m-%d')  #转换成固定格式
    list1.append(y)
quotesdf_ori=pd.DataFrame(quotes,index=list1)
quotesdf=quotesdf_ori.drop(['date','adjclose'],axis=1)
quotesdf


输出结果:
在这里插入图片描述

2、json.loads()

json.load()函数是将字符串转化成字典

3、date.strftime()

将date格式转化成固定格式的字符串

4、time.strptime()

将字符串转化成struct_time,struct_time可以通过tm_year,tm_mon,tm_mday获取日期的年月日

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值