三.爬虫开始:

….第三方类库: request模块

安装:

pip install request
例子:
(1)你喜欢的明星
import  requests
query = input("输入一个你喜欢的明星")
url = 'http://www.baidu.com/s?word={query}'
dic = {
    "Use-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0"
}
resp =requests.get(url,headers=dic)
print(resp)
print(resp.text)
resp.close()    
(2)百度翻译
import  requests
url = "https://fanyi.baidu.com/sug"
s = input("请输入你想输入的英文单词")
dat = {"kw":s}
# 请求用post 发送的数据必须放在字典中,通过data来传递
resp = requests.post(url,data=dat)
print(resp.json())#将服务器的内容处理成json()=》dict(字典)
resp.close()
(3)豆瓣
import  requests
url = "https://movie.douban.com/j/search_subjects"
param={
        "type""tv",
        "tag""热门",
        "page_limit""50",
        "page_start""0"
}
headers ={
 "User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
resp = requests.get(url=url,params=param,headers=headers)
print(resp.json())
#反爬了 1.use-agent
#'User-Agent': 'python-requests/2.27.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}
resp.close()

数据解析:

1.re解析:正则表达式

元字符
元字符 匹配内容
. 匹配除换行符以外的任意字符
\w 匹配所有普通字符(数字、字母或下划线)
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾
^ 匹配字符串的开始位置
$ 匹配字符串的结尾位置
\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
a|b 匹配字符 a 或字符 b
() 正则表达式分组所用符号,匹配括号内的表达式,表示一个组。
[…] 匹配字符组中的字符
[^…] 匹配除了字符组中字符的所有字符
量词
量词 用法说明
* 重复零次或者更多次
+ 重复一次或者更多次
重复0次或者一次
{n} 重复n次
{n,} 重复n次或者更多次
{n,m} 重复n到m次
字符组
[]
正则 待匹配字符 匹配结果 说明
[0123456789] 8 True 在一个字符组里枚举所有字符,字符组里的任意一个字符 和"待匹配字符"相同都视为可以匹配。
[0123456789] a False 由于字符组中没有 "a" 字符,所以不能匹配。
[0-9] 7 True 也可以用-表示范围,[0-9] 就和 [0123456789] 是一个意思。
[a-z] s True 同样的如果要匹配所有的小写字母,直接用 [a-z] 就可以表示。
[A-Z] B True [A-Z] 就表示所有的大写字母。
[0-9a-fA-F] e True 可以匹配数字,大小写形式的 a~f,用来验证十六进制字符。
贪婪模式非贪婪模式
元字符(贪婪模式) 非贪婪模式
* *?
+ +?
??
{n,m} {n,m}?
正则表达式转义
\
+ ? ^ $ [] () {} | \
re模块常用方法
1) re.compile()
regex=re.compile(pattern,flags=0)
# 预加载正则表达式
obj = re.compile(r"\d+")
  • pattern:正则表达式对象。
  • flags:代表功能标志位,扩展正则表达式的匹配。
2) re.findall()
re.findall(pattern,string,flags=0)
#findall 的意思是匹配正则中的所有符合的内容
import  re
list = re.findall(r"\d+","我的电话号是:10086,我的女朋友的电话哦号码是:1111111")
print(list)
  • pattern:正则表达式对象。
  • string:目标字符串
  • flags:代表功能标志位,扩展正则表达式的匹配。
3) regex.findall()
regex.findall(string,pos,endpos)
#finditer 匹配字符串中的所有的内容(返回的是迭代器),从迭代器中拿到需要的内容要用group()
it = re.finditer(r"\d+","我的电话号是:10086,我的女朋友的电话哦号码是:1111111")
for i in it :
    print(i.group())
  • string 目标字符串。
  • pos 截取目标字符串的开始匹配位置。
  • endpos 截取目标字符串的结束匹配位置。
4) re.split()
re.split(pattern,string,flags = 0)
  • pattern:正则表达式。
  • string:目标字符串。
  • flags:功能标志位,扩展正则表达式的匹配。
re.sub(pattern,replace,string,max,flags = 0)
  • pattern:正则表达式。
  • replace:替换的字符串。
  • string:目标字符串。
  • max:最多替换几处,默认替换全部,
  • flags:功能标志位,扩展正则表达式的匹配。
5) re.search()
re.search(pattern,string,flags=0)
# search返回的结果是match对象,拿数据需要.group()<全文件检索一个有就返回》
s = re.search(r"\d+","我的电话号是:10086,我的女朋友的电话哦号码是:1111111")
print(s.group()) 
  • pattern:正则表达式

  • string:目标字符串

    # match返回的结果是《从头开始匹配》[^]
    s = re.match(r"\d+","10086,我的女朋友的电话哦号码是:1111111")
    print(s.group())
正则的例子:
1.小试牛刀
import  re
# 从正则里面提取内容  (?P<分组名字>正则) 可以取到正则中的数据
re.s
s ="""<div class='container'>我的</div>
      <div class='header'>你的</div>
      <div class='inner'>周杰伦</div>
       <div class='logo'>林俊杰</div>"""

obj = re.compile(r"<div class='(?P<id>.*?)'>(?P<mingzi>.*?)</div>",re.S)#re.S让点匹配换行符 不会断
ret = obj.finditer(s)
for i in ret:
    print(i.group("mingzi"))
    print(i.group("id"))
ret.close()
2.豆瓣top250
# 通过requests来提取页面的源代码 re来获取有效的信息
import re
import requests
import csv
s = 0
url = "https://movie.douban.com/top250?start={s}&filter="
headers = {"User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"}
resp = requests.get(url,headers=headers)
# print(resp.text)
#数据解析
obj = re.compile(r'<li>.*?<span class="title">(?P<name>.*?)</span>.*?'
                 r'<p class="">.*?<br>(?P<year>.*?)&nbsp.*?<div class="star">.*?'
                 r'<span class="rating_num" property="v:average">(?P<score>.*?)</span>'
                 r'.*?<span>(?P<number>.*?)</span>',re.S)
# obj =re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)'
#                 r'</span>.*?<p class="">.*?<br>(?P<year>.*?)&nbsp.*?<span class="rating5-t"></span>'
#                 r'.*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>.*?'
#                 r'<span property="v:best" content="10.0"></span>.*?<span>(?P<number>.*?)</span>.*?</li>',re.S)
#开始匹配
ret = obj.finditer(resp.text)
#保存文件
f = open("data.csv",mode="w",encoding="utf-8")
csvwriter = csv.writer(f)
for it in ret:
    # print(it.group("name"))
    # print(it.group("year").strip())
    # print(it.group("score"))
    # print(it.group("number"))
    dic = it.groupdict()
    dic["year"] = dic["year"].strip()
    csvwriter.writerow(dic.values())
f.close()
ret.close()
print("over")
3.电影天堂
# 定位到2022必看片子,2022必看中的提到的页面的地址
#请求子页面的链接地址得到我们想要的链接地址。。。
import requests
import re
domain ="https://dytt89.com/"
headers = "'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'"
resp = requests.get(domain)#网站加密,防火墙。。。证书。。,verify=False
resp.encoding = 'gb2312' #指定字符集 默认是utf-8

#拿到ul里面的li
obj_1 =re.compile(r'2022必看热片.*?<ul>(?P<ur>.*?)</ul>',re.S)
obj_2 =re.compile(r"<a href='(?P<href>.*?)'",re.S)
obj_3 =re.compile(r'◎片  名(?P<movie>.*?)<br />.*?<li><a href="(?P<down_load>.*?)">',re.S)
result_1 = obj_1.finditer(resp.text)
child_href_list =[]
for it in result_1:
    ur = it.group("ur")
    # print(it.group(ur))

    #提取子页面链接
    result_2 = obj_2.finditer(ur)
    for itt in result_2:
        # 拼接网站的地址 域名+子页面地址
        child_href = domain + itt.group("href").strip("/")
        # print(itt.group("href"))
        # print(child_href)
        child_href_list.append(child_href)#把子页面的链接保存起来
#拿到url里面的网址 提取到子页面的地址
for href in child_href_list:
    child_resp = requests.get(href)
    child_resp.encoding="gb2312"
    # print(child_resp.text)
    result_3 =obj_3.search(child_resp.text)
    print(result_3.group("movie"))
    print(result_3.group("down_load"))
    break#测试

2.bs4解析

安装:

pip install bs4

find():查找某个元素("标签",xx={"属性",值}) 。。。。只找一个

page.find("table",class_="hq_table")

find_all():查找某个元素("标签",xx={"属性",值}) 。。。。找所有

bs4的例子:
1.北京新发地
#北京新发地
import re
import requests
from bs4 import BeautifulSoup
import csv
url = "http://www.xinfadi.com.cn/getPriceData.html"
headers ={"User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"}
resp =requests.post(url,headers=headers)

f = open("菜价.csv",mode="w")
csvwriter=csv.writer(f)
# print(resp.text)
#解析数据
# 把页面源代码交给BeautifulSoup进行处理生成bs对象
page = BeautifulSoup(resp.text,"html.parser"#指定是html解析器
# 从bs对象中查找数据
#find(标签,属性=值)
# findall(标签,属性=值)
#下面是在XHR 里面 演示的是页面的 不会
table =page.find("table",class_="hq_table")#class是python的关键字
# table =page.find("table",attrs={"class":"hq_table"})和上一行意思一样,此时可以避免class
# 拿到所有的数据
trs = table.find_all("tr")[1:]#从第一行开始
for tr in trs:#每一行
    tds = tr.find_all("td")#拿到每行的td
    name = tds[0].text #拿到每行的标签标记的内容 名称
    low = tds[1].text
    hight = tds[2].text
    gui = tds[3].text
    a = tds[4].text
    b = tds[5].text
    csvwriter.writerow([name,low,hight,a,b])
f.close()
resp.close()
print("over")
2.唯美壁纸
#唯美壁纸https://www.umeitu.com/bizhitupian/weimeibizhi/
#拿到主页面的页面源代码 ,找到子页面的链接地址,href
#通过href找到子页面然后找到子页面的图片的内容 img-src
#下载图片
import requests
from bs4 import BeautifulSoup
import time

domain = "https://www.umeitu.com/bizhitupian/weimeibizhi/"
domain_1="https://www.umeitu.com/"#拼接用的url

resp = requests.get(domain)
resp.encoding="utf-8"
child_href_list =[]
# print(resp.text)
#把源代码交给bs
main_page = BeautifulSoup(resp.text,"html.parser")
alist = main_page.find("div",class_="TypeList").find_all("a")#把范围第一次缩小
# print(alist)
for a in alist:
    #child_href = domain + itt.group("href").strip("/")
    child_href = domain_1 + a.get("href").strip("/")
    child_href_list.append(child_href)  # 把子页面的链接保存起来
    # print(a.get('href'))#直接拿到href
    # print(child_href)
    #反复比对
    #https://www.umeitu.com/bizhitupian/weimeibizhi/225260.htm
    #https://www.umeitu.com/bizhitupian/bizhitupian/weimeibizhi/225260.htm
    #https://www.umeitu.com/bizhitupian/weimeibizhi/bizhitupian/weimeibizhi/225260.htm
    #拿到子页面的源代码
    for href in child_href_list:
        child_href_resp = requests.get(child_href)
        child_href_resp.encoding = "utf-8"
        child_page_resp_text = child_href_resp.text

        # 从页面拿图片的下载路径
        child_page = BeautifulSoup(child_page_resp_text, "html.parser")
        p = child_page.find("p", align="center")
        # print(img)
        img = p.find("img")
        src = img.get("src")
        # print(img.get("src"))
        # 下载图片
        img_resp = requests.get(src)
        # img_resp.content#这里拿到字节
        img_name = src.split("/")[-1]  # 这里拿到url的最后的一个/以后的内容
        with open("img/" + img_name, mode="wb"as f:
            f.write(img_resp.content)
        print("over")
        time.sleep(1)

3.Xpath解析

XPath(全称:XML Path Language)即 XML 路径语言,它是一门在 XML 文档中查找信息的语言,最初被用来搜寻 XML 文档,同时它也适用于搜索 HTML 文档。因此,在爬虫过程中可以使用 XPath 来提取相应的数据。

安装:

pip install lxml
from lxml import html
etree=html.etree
xpath的入门例子:
1.了解xml
# xpath 是在xml 文件中搜索内容的一门语言
# html 是xml 的子集  节点 (父节点 兄弟《同胞节点》)节点) 利用节点的关系来找
# python 安装lxml模块
# 解析xml
from lxml import html
xml = """"
<book>
    <id>1</id>
    <name>野花遍地香</name>
    <price>1.23</price>
    <nick>臭豆腐</nick>
    <author>
        <nick id="10086">周大强</nick>
        <nick id="10010">周杰伦</nick>
        <nick id="11111">周树人</nick>
        <nick id="12138">蔡依林</nick>     
        <div>
            <nick>惹了1</nick>
        </div>    
        <span>
            <nick>惹了2</nick>
        </span>       
    </author>

    <partner>
        <nick id="ppb">胖胖成</nick>
        <nick id="ppbc">胖胖称</nick>
    </partner>
</book>
"""

tree = html.fromstring(xml)
print(tree)
para = tree.xpath("//book/name/text()")#/text()拿取文本
para = tree.xpath("//book/author//nick/text()")#后代//
para = tree.xpath("//book/author/*/nick/text()")#通配符*
para = tree.xpath("//book//nick/text()")#全部的
for e in para:
    print(e)
2.例子
from lxml import html
tree = html.parse("cheshi.html")
para = tree.xpath("//html/body/ul/li[1]/a/text()")#xpath是从1开始算的
para = tree.xpath("//html/body/ol/li/a[@href='http:dapao']/text()")定向href
print(para)
for e in para:
    print(e)


ol_li_list = tree.xpath("//html/body/ol/li")
for li in ol_li_list:
    #从每个li中提取到文字
    ret_1 = li.xpath(".//a/text()")#相对查找 .
    print(ret_1)
    ret_2 = li.xpath(".//a/@href")#拿对应的属性的值@href
    print(ret_2)

print(tree.xpath("//html/body/ul/li/a/@href"))

print(tree.xpath("/html/body/div[1]/text()"))
3.猪八戒网
#https://beijing.zbj.com/search/f/?type=new&kw=saas 猪八戒网
import requests
from lxml import html

url = "https://beijing.zbj.com/search/f/?type=new&kw=saas"
resp = requests.get(url)
# print(resp.text)
#解析
ret = html.fromstring(resp.text)
#拿到每一个服务商的div
divs = ret.xpath("/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div")
for div in divs:
    price = div.xpath("./div/div/a[2]/div[2]/div[1]/span[1]/text()")[0].strip("¥")
    title = "saas".join(div.xpath("./div/div/a[2]/div[2]/div[2]/p/text()"))
    com_name =  div.xpath("./div/div/a[1]/div[1]/div[1]/span/text()")[0]
    print(title)
posted on 2022-03-31 11:49  Steam残酷  阅读(104)  评论(0)    收藏  举报