网络爬虫2
程序员文章站
2022-05-04 11:28:18
...
网络爬虫2
正则
-
re.match()
:从头开始匹配 -
re.search()
:不从头开始匹配 -
re.spilt()
:切割,返回列表参数maxsplit
指定最大的切割数,默认全部 -
re.findall()
:以列表形式返回能匹配的全部字符串 -
re.finditer()
:功能与上相同,但返回的是一个迭代器
BeautifulSoup
-
可以从HTML或XML文件中提取数据的Python库
-
安装:
apt-get install Python-bs4 # 或 pip install beautifulsoup4 # lxml安装 pip install lxml
-
使用
-
导入模块
from bs4 import BeautifulSoup as Bs
-
创建对象:
-
字符串创建
soup = Bs(html_str,'lxml',from_encoding='utf-8')
-
html文件创建
soup = Bs(open('index.html'))
-
-
利用soup加标记名就可以获取这些标记的内容,但只是第一个
-
soup.title
:输出的是第一个title标签 -
soup.title.name
:第一个title标签的名字 -
soup.p['class']
:第一个P标签的class属性(多个属性则返回一个列表) -
soup.p.get('class')
:与上一样 -
soup.p.string
:第一个p标签的内容
-
-
数据存储
-
JSON写入
import json str = [{"name":"范晓昊","age":18."gender":"男"}] with open('json_str.json','w') as f: f.write(json.dumps(str,indent=2,ensure_ascii=Flase))
-
JSON读取
json.loads(str) # 可以把json字符串转化成Python对象(列表)
-
csv写入(字典写入)
import csv titles = ['name','age'] rows = [{'name':'范晓昊','age':18}, {'naem':'李二狗','age':19}] with open('csvfile.csv','w',newline='',encoding='utf-8') as f: f_csv = csv.DictWriter(f,titles) # 获取文件”写笔“,此时并不会重写标题 f_csv.writeheader() # 写入记录标题 f_csv.writerows() # 写入多行记录
-
csv写入(列表写入)
import csv title = ['name':'age'] rows = [("范晓昊",21), ("李二狗",20)] with open("csvfile.csv",'w',newlone='',encoding='utf-8') as f: f_csv = csv.writer(f) f_csv.wirterow(titles) f_csv.writerows(rows)
-
csv读取(字典读取)
import csv with open('data.csv','r') as f: reader = csv.DictReader(f) for i in reader: name = i["name"] age = i["age"] print({"name":name,"age":age})
-
csv读取(列表读取)
import csv with open('data.csv','r') as f: reader = csv.reader(f) # 返回读取迭代器 titles = next(reader) # 提取文件记录标题 for i in reader: # 遍历向下迭代 name = i[0] age = i[1] print({"name":name,"age":age})
多媒体文件存储
-
一种是获取URL链接存储
一种是直接下载到本地
-
urllib
模块中的urlretrieve()
可将数据下载到本地(urllib.request
中)def report(count, blockSize, totalSize): '''回调函数,一行显示进度条''' percent = int(count * blockSize * 100 / totalSize) sys.stdout.write("\r%d%%" % percent + ' complete') sys.stdout.write('[%-50s] %s' % ('=' * int(math.floor(count * blockSize * 50 / totalSize)), percent)) sys.stdout.flush() urlretrieve(video_url,video_name, report)
urlparse模块
- urlparse.urlparse():将url分为6个部分,返回一个包含6个字符串项目的元组
- urlparse.urljoin():将相对地址组合成一个url,对输入没什么限制,但开头必须是协议
selenium与phantomJS
-
selenium是一个web的自动化测试工具,可以通过命令来自动操作(需要下载对应浏览器的driver)
- 可以通过pip install 来安装
-
phantomJS是一款*面的浏览器
-
使用
from selenium import webdiver # 实例化一个浏览器 driver = webdriver.Chrome('./chromedriver') # 也可以直接放在user/bin或user/local/bin下 # 发送请求 driver.get('url') # 退出浏览器 diver.quit()
-
注意
- 获取文本和获取属性时:先定位到元素,然后调用
.txt
或者get_attribute
方法来获取 - selenium获取的页面数据时浏览器中的elements的内容
-
find_element
和find_elements
- 前者返回一个element,如果没有就会报错
- 后者返回一个列表,没有就为空列表
- 在判断下一页的时候,使用find_elements来根据结果的列表判断
- 如果页面中包含
iframe
,frame
,需要先调用driver.switch_to.frame
的方法切换到frame中才能定位元素(传ID:name)
- 如果页面中包含
- selenium请求第一页的时候会等待页面加载完之后再获取数据,但是在点击翻页之后,会直接马上获取数据,此时可能会报错,因为数据还没有加载出来,需要
time.sleep
下
- 获取文本和获取属性时:先定位到元素,然后调用
数据去重
- 使用数据库建立关键字段(一个或多个)建立索引进行去重
- 根据url地址去重
- 使用场景:url地址对应的数据不会变的情况,url地址能够唯一判别一个数据的情况
- 思路:url存在redis中
- 拿到url地址,判断url在Redis的url集合中是否存在
- 存在:说明url已经被爬取过,不需在请求
- 不存在:没有的话,就请求,然后把该url存入Redis的集合中
- 布隆过滤器:
- 拿到url地址,判断url在Redis的url集合中是否存在
- 根据数据本身去重
- 选择特定的字段,使用加密算法(md5、shal)将字段进行加密,生成字符串,存入Redis的集合中
- 后续新来一条数据,同样的方法加密,在与Redis中的字符串对比,如果相同则存在,选择更新或pass,否则数据不存在,直接插入
END。
上一篇: 手机腾讯网前端框架 mt 2.1 发布
下一篇: Python: 网络爬虫 -2