爬虫学习笔记

爬虫学习笔记

list

  1. extend函数 将两个list连起来

  2. 整齐打印抓到的html页面:直接print re.text就行

  3. str 替换函数,replace,替换字符串内容

  4. list index()求 元素的下标

  5. 字符串中加数字: sd=’%s_%s’%(i,t)
    . for (i1, i2) in zip(list1,list2): 同时遍历两个list

  6. .找class span中的内容 self.title.append(lable.split(“\”“)[1])

  7. str.isalpha()判断是否是字母

  8. str.isdigit()判断是否是数字 判断是否包含字母或者数字:re.search(‘[a-z]’,str)

  9. jieba分词:

    txt = open("bxj.txt", "r", encoding='utf-8').read()
           words = jieba.lcut(txt)  # words全部截取
           counts = {}
           for word in words:
               if len(word) == 1:
                   continue
               else:
                   counts[word] = counts.get(word, 0) + 1
           sd=sorted(counts.items(),key=lambda asd:asd[1],reverse=True)
  10. tuple 强制转换转list
    sd=list(sd)

解析数据

Beautifulsoup

初始化

soup = BeautifulSoup(html, ‘html.parser’)

深层次查找标签

bs4可以通过find 或者find_all()返回后再次调用,find或者find_all()

然后,通过result[‘href’]得到href的标签

tag

有两个属性: name,attrs

  1. 找出所有链接
    names=soup.find_all(‘a’,{‘class’:’headpic’})
    for each in names:
    # print(each)
    href=each[‘href’]
    print(href)

  2. bs4 find_all(‘td’)找出所有,其他也一样

  3. 找出 sd=message.find_all(‘td’,{“class”:”tWhite”})

  4. 提取信息 只有一条的情况下: sd[0].getText

  5. a=each.find(‘a’) print(a.text)得到a 中间text的文件内容

  6. a=each.find(‘a’) print(a[href])找到a标签中的href

  7. tr=soup.find(attrs{‘id’:’places_area_row’}) 找出id 属性值为‘’ 的数据

  8. bs 对象分为4大类 Tag NavigableString BeautifulSoup Comment
    tag:有两个属性: attrs name name 打印出来 标签的类别 比如 span
    tag.attrs: {‘class’: [‘f666’]}找出span中的属性
    tag.text打印出标签内部的内容

  9. 找到< li >中的文字,用.string方法

lxml

导入方式
import lxml.html//
  1. tree=lxml.html.fromstring(html)

    . td=tree.cssselect(‘tr# places_area__row > td.w2p_fw’)[0]
    代表id,首先找到tr为places_area的元素,然后找到td类属性为w2p_fw的元素

  2. 然后text_content得到内容

  3. 选择a内span 标签 : a span

  4. title 属性为 home 的所有标签 a[title=home]

  5. 选择class=link 的所有f a.link
获得div标签下的所有class

div_class=tree.xpath(‘//div/@class’)
print(div_class)

xpath学习

page = etree.HTML(html.lower().decode(‘utf-8’))

定位html标签,相对路径,绝对路径

  • 绝对
    path.xpath(u”/html/body/p”)
  • 相对
    path.xpath(“//p”) 找出所有的p标签

定位到“

World News only on this page


p = page.xpath(u”/html/body/p[@style=’font-size: 200%’]”)
用如@name, @id, @value, @href, @src, @class….

函数text 取出p中的文本
position 是节点的位置 li[position()=2]”表示取得第二个li节点

代表所有的节点,比如用”/html/body//span可以取出body下第二级的所有span,而不管它上一级是div还是p或是其它什么东东。

href 找出所有的a标签和内容

hrefs=page.xpath(u”//a”)
for href in hrefs:
print(href.attrib)
print(href.text)’
找出链接
print(href.get(‘href’))

position

hrefs=page.xpath(u”//a[position()=2]”)
找出所有href标签中的第二个

取不到的内容

用tail 属性

print (u.tail)
结束节点后面的内容

解析字符串

处理url

  1. urljoin from urlparse import url

urls.append(urljoin(“https://tieba.baidu.com/“,each.get(‘href’)))

返回response的url: response.geturl()
  1. str 的操作:info=”.join(info.split()) 去掉所有的空格和换行符
  2. 不换行输出 print(‘123123’, end=”)

  3. plt.rcParams[‘font.sans-serif’] = [‘SimHei’] 解决中文乱
    码问题

  4. dic.get(‘fan’)==None dic[‘fan’]=1 dic检查元素是否存在 以及添加元素的方法

解析json

json.loads()

  1. 将json结构的str 转换为 python类型数据结构 dict类型

json.dumps()

  1. 将python 的数据结构 dict 转换为json结构的str

抓取知乎内容

抓取我的收藏:

li class=” “> a class=” “> 2

urlib 和urllib2学习

标准款

response=urllib2.open(‘http://python.org/‘)
html=response.read()

加上header 和数据

user_agent='Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Mobile Safari/537.36'

headers={'User-Agent':user_agent}

values={‘name’ : ‘Michael Foord’, ‘location’ : ‘Northampton’, ‘language’ : ‘Python’ }
headers={‘user_agent’:user_agent)
data=urllib.urlencode(values)
req=urllib2.request(‘http://python.org‘,data,headers)
response=urllib2.urlopen(req,)
html=response.read()

加上代理

proxy_handler=urllib2.ProxyHandler({“http”:”http://114.215.95.188:3128“})

opener=urllib2.build_opener(proxy_handler)

urllib2.install_opener(opener)

加上cookie

  1. 设置cookie cookie=cookielib.CookieJar()
  2. build一个opener opener=urlliib2.build_opener(urllib.HTTPCookieProcessor(cj))
  3. 使用opener打开构建的request请求

内容保存到本地

将html 写入txt
html=req.text
with open('zhihu_html.text','w') as opener:
    opener.write(html)
    dest_dir为本地地址

urllib.urlretrieve(url , dest_dir)

将url存在本地磁盘的方法

  1. 将抓取下来的网页按照域名保存为一个个文件夹,然后将域名后面的东西保存为文件地址

解决乱码

如果原始是GBK
html=unicode(html,’GBK’).encode(‘UTF-8’)

判断遍历的最大深度

最原始的网页深度为 1:
如果 抓取到的网页来自原始网页 被抓取的网页深度+1

如果一个url的深度大于最大深度 就不把他加在队列中
慢慢的 队列就空了,抓取停止了

也就是说 设置最大深度为4

最多再抓取三层的信息


项目总结 2018.4.19

算是第一个爬虫小项目: 先总结一下

  • 开始:通过crawler 方法,传入基本信息

  • 维护一个url队列
    从最初的url抓取到的url 如果抓取过,就 添加在对列中, deepth+=1

  • 如果url在本地磁盘缓存中,html就从本地缓存中调用
    否则进行下载,并且将下载的页面写入缓存

    • 解析:通过正则解析html 找到需要的url
      一个html页面所有的url抓取完毕, 该html对应的url出队列
  • 定时,在下载时,为了防止ip被封,写一个定时类,可以在每次下载时延缓一定的时间

  • 当队列为空,所有的抓取完毕时,调用回调函数,将信息写在csv文件中(这是个缺点,如果网络中断,岂不是之前的信息都要gg)

  • 在抓取完一个url后,将html 文件写入本地缓存

文件功能:

playground.py:程序的入口
Downloader.py:下载方法的实现
disk_cache.py:页面缓存的实现

待完善:

  1. 用芒果db来代替本地储存
  2. 对爬虫功能的增加,比如识破验证码,处理ajax请求
  3. csv文件那块还要再商议一下
  4. 如果能用代理的话,也不错
  5. 分布式定时任务框架rabbitMq 和celery学一下

Mongo DB的使用

概念

集合:

mogod -dbpath 是储存文档的地方,相当于mysql的表格
集合没有固定的结构,比较松散,但集合中的文档,一般都有相关性

当插入一个文档时,集合就会建立

document

为主键 |

SQL术语/概念MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins表连接,MongoDB不支持
primary keyprimary key主键,MongoDB自动将_id字段设置

数据类型

ObjectId 类似唯一的主键

运行mongoDB

mongod

常用shell

show dbs
use db

dbname.system.* //查看数据库的所有信息

insert
WriteResult({ “nInserted” : 1 })

删除当前数据库
db.dropDatabase()

创建集合

db.createCollection(“runoob”)

显示所有集合

show collections

插入文档

以下文档可以存储在 MongoDB 的 runoob 数据库 的 col 集合中:

db.COLLECTION_NAME.insert(document)

db.col.insert({title: ‘MongoDB 教程’, description: ‘MongoDB 是一个 Nosql 数据库’, by: ‘菜鸟教程’, url: ‘http://www.runoob.com‘, tags: [‘mongodb’, ‘database’, ‘NoSQL’], likes: 100 })
终端连接服务器进入shell :mongo

查看集合中的文档

db.col.find()
db.collections.count() 查看表中的元素个数

python连接mongodb 放在local中

  1. 默认端口号27017
    2.终端输入 mongo 进入sql命令行

mysql 为key-value 模式

mongodb 的配置文件
/usr/local/etc

文件默认路径:/usr/local/var/mongodb

修改了数据库路径

赋权: sudo chown id -u /Users/fanjialiang2401/data/mongo/

查看mongodb 是否在运行

mongodb 正确退出方式:
mongo // 从linux命令行进入mongod命令行

use admin // 切换到管理员模式

db.shutdownServer() // 关闭mongodb服务

pymongo

shell

  1. show dbs
  2. use db
  3. db.webpage.find()找出collection为webpage的所有元素
  4. db.webpage.count()
    . db.webpage.find()
  5. 搜索所有的值
for item in table.find():
    print(item)
  1. db.collection.createIndex( { name: -1 } )
    7.db.myColl.find( { category: “cafe” } )
  2. db.myColl.createIndex(
    { score: 1, price: 1, category: 1 },
    { collation: { locale: “fr” } } )
  3. db.myColl.find( { score: 5, category: “cafe” } )

照片 2018-03-27 下午8.06.04

高端方法

selenium


def get_html():
    driver=webdriver.Firefox()
    html=driver.get('https://search.jd.com/search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&gp=2&cid2=653&cid3=655&ev=exbrand_%E4%B8%89%E6%98%9F%28SAMSUNG%29%5E&page=1&s=1&click=0')
    time.sleep(3)
    driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
    time.sleep(3)
    html = driver.find_element_by_xpath("//*").get_attribute("outerHTML")
    return html


python shell

  1. client=MongoClient(‘localhost’,27017)
  2. db = client.primer

  3. db.webpage.find()找出collection为webpage的所有元素
    . tablename.remove({“name”: “mike”})

  4. counts=table_name.count()
    coll = db.dataset

删除数据库

client

  • 查看表中有多少元素
    counts=table_name.count()
    print(‘总行数:%s’%counts)

  • 找到一条记录
    cols=table_name.find_one()

  • 找特定的某一行

result=table_name.find({“name”:”fanjialiang”})

连接到对应的数据库

连接数据库名为primer
db = client.primer
连接名称为dataset的collctions
coll = db.dataset

db=conn.get_database('local')
colletion=db.collection_names()

查找

result=db.webpage.find({‘url’:url})//查找出来的是游标

  • result=db.webpage.find_one({‘_id’:url})
    result= ‘ads’
    for i in result:
    print(i)

将url设为id

db.webpage.update({‘_id’:url},{‘$set’:{‘html’:html}},upsert=True)

删除

 tablename.remove({"name": "mike"})
  • 插入
    table_name.insert({“name”:’fanjialiang’,”age”:18})

ps aux | grep mongo 查看mongodb 然后kill掉


requests

请求格式

response=requests.get(url=self.begin_url,headers=self.headers,cookies=CookieJar)

下载文件:

url=http://flupy.org/data/flags/fr/fr.gif

iamge=request.get(url).content

open(‘a.gif,’wb’) as opener:

opener.write(image)

解析csv文件

file=open(‘csv/top-1m.csv.zip’,’r’)
with ZipFile(file) as zf:
csv_filename=zf.namelist()[0]
for _,website in csv.reader(zf.open(csv_filename)):
urls.append(‘http://’+website)

下载最受欢迎的网站

下载一千个网页:
- 如果国内访问不到,设置一个超时时间,返回url,添加在错误url list中
- 如果能访问到,加在mongo数据库中,并且为加入的url,创建一个index序号,作为主键
- 计算访问花费的总时间。
- 设置数据库名称
- 回调函数先不创建



代理项目

  1. 不断的从互联网上抓取代理
  2. 将抓取下来的代理写在csv中
  3. 将好的代理筛选出来,返回一个List
  4. 抓取其他网站时,采用从代理池中随机选择一个

百度贴吧项目

  1. 将title抓下来
    将内容抓下来
    然后打印title,和对应的内容

每打印一行,输出换行

2.将页数抓下来,维持一个队列,每次从队列中取url,如果没访问过加加在队列中,否则跳过。

  1. 将抓下来的内容存放在mongoDB中 起名NBA50大

抓取淘宝模特信息

  1. 在主页面把模特的href 抓下来,然后进入每个的个人页面href

  2. 进入网页后,抓取个人域名,在进入每个人的个人域名把照片抓取下来

  3. 在个人页面上,把个人信息抓取下来,储存为csv文件
    身高, 三围 , 个人页面, 等等

项目流程

  • downloader类负责下载 不要scrapeCallback方法了

  • hrottle类负责 限制速度

  • scrapeCallback为回调类,在完成下载后调用回调类将消息写入硬盘

  • diskCache 类负责将抓取的内容写到硬盘中

  • Link_crawler为总的开始

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值