基于python的爬虫方法总结(一)

爬取的方法很多,,但是不管用什么方法总结起来就3大步

  1. 确定要爬取的URL地址
  2. 向网站发请求获取相应的HTML页面
  3. 提取HTML页面中有用的数据

一,获取静态页面数据方法

urllib方法

1、python2 :urllib、urllib2
2、python3 :urllib.request
对应的版本不同,python的包也不同,
以python3 为例
爬取贴吧图片的部分代码
(这里要注意下url中的文字要经过url编码
方法有:
1.a=urlencode({‘kw’,‘地下城’})
a=‘kw=XXXXXXXXXXXXXXX’
2.a=quote(‘地下城’)
a=‘XXXXXXXXXXXX’ (unquote进行反url编码)
例:

  class BaiduSpider(object):
    def __init__(self):
        self.baseurl = "http://tieba.baidu.com/f?"
        self.headers = {"User-Agent":"Mozilla/5.0 "}
     
   #获取页面    
    def getPage(self,url):
        req =urllib.request.Request(url,headers=self.headers)
        res = urllib.request.urlopen(req)
        html =res.read().decode("utf-8")
        return html
    #解析页面
    def parsePage(self):
        pass
    #保存数据
    def writePage(self,filename,html):
        with open(filename,"w",encoding="utf-8") as f:
            f.write(html)

如果返回的有json文件的话 可以通过dict = json.loads(html),把返回的数据变成一个字典,在进一步取值。

requests方法

class NoteSpider(object):
    def __init__(self):
        self.url ="http://code.tarena.com.cn"
        self.headers ={"User-Agent":"Mozilla/5.0"}
        self.proxies = {"http":"http:164.215.6.22:8888"}
        
def getprasepage(self):
    request=requests.get(self.url,auth=self,proxies=self.proxies,headers=self.headers)
    request.encoding ='utf-8'
    html =request.text
    p=re.compile('正则表达式',re.S)
    rlist =p.findall(html)
    self.writepage(rlist)

def writepage(self,rlist):
    pass

selenium方法

爬取快代理的示例:

from selenium import webdriver
import time 
opt = webdriver.ChromeOptions()
opt.set_headless()
driver =webdriver.Chrome(options=opt)

while True:
    print('页数:',page)
    driver.get('https://www.kuaidaili.com/free/inha/'+str(page)+'/')
    time.sleep(1)
    hosts=driver.find_elements_by_xpath("//td[@ data-title='IP']")
    ports=driver.find_elements_by_xpath("//td[@ data-title='PORT']")
    for host,port in zip(hosts,ports):
        test_id=host.text+':'+port.text
        with open('代理ip.txt','a',encoding='utf-8') as f:
            f.write(test_id+'\n')
    page+=1
    if page ==6:
        break
driver.quit()

BeautifulSoup方法

示例:

soup =BeautifulSoup(html,'lxml')
rlist = soup.find_all('div',{"class":"test"})
    
for r in r1list:
    print(r.,div.string)

Scrapy框架方法

emmm,这个框架方法内容下篇再说明有点多

二,解析静态页面数据方法

re正则解析

1.创建正则对象
2.进行匹配,返回一个匹配的结果列表

p = re.compile('<div class="animal">.*?title="(.*?)".*?class="content">(.*?)</p>',re.S)
rList = p.findall(html)

xpath解析

1.创建xpath待解析对象
2.进行xpath解析,结果一定是列表
xpath的一些语法:
/:从当前节点找子结点(非后代节点),返回节点对象
例:
//price /book :查找父节点为price的所有book节点,返回节点对象
// : 从整个文档中查找节点,返回节点对象
例:
//price //book//name 查找price节点的后代book节点后代的name节点,返回节点对象
contains() :匹配一个属性值中包含某些字符串的节点
例:
//title[contains(@class,“e”)]查找title节点中有class属性,且class属性的值中包含一个e的节点,返回节点对象
@ : 节点中含某个属性
例:
//title[@class=“en”]查找class='en’的title节点,返回节点对象
//title/@class 查找有class的title节点,返回class的值
//title[@class=“en”]/text()查找class='en’的title节点,返回符合要求节点里的所有文本。

使用方法:
parseHtml = etree.HTML(html)
r1 = parseHtml.xpath(’//a/@href’)

selenium中独有的find_element

#返回单个节点对象
elmt= driver.find_element_by_name( ‘text’)
elmt= driver.find_element_by_class_name( ‘text’)
elmt= driver.find_element_by_id( ‘text’)
text=elmt.text #获取节点的文本内容
#返回节点列表
text = driver.find_elements_by_id( ‘text’)

BeautifulSoup中独特的解析

创建解析对象(解析方式为lxml或xml)
soup = BeautifulSoup(html,‘lxml’)
查找节点对象,返回的是节点对象列表,用get_text()方法获取文本

 rlist = soup.find_all('div',{'id':''})
 for r in rlist:
 	text=r.get_text()

三,发送的请求类型(以requsets)

带参数的请求
params={‘参数名’:‘参数值’,‘参数名’:‘参数值’,‘参数名’:‘参数值’,…}
自动拼接为url参数名=参数值&参数名=参数值
wd为参数名 flask为参数值
例:https://www.baidu.com/s ? wd=flask
res = requests.get(url, params=params,headers=headers)

post请求

data={‘参数名’:‘参数值’…}
#data为需要发送的表单数据。
requests.post(url,data=data,headers=headers)
cookie请求
requests.get(url,data=data,headers=headers)
语句不变,只是headers中需要带有cookie中的参数,一般用于登录网站。

带有动态ajax的网页请求

这个方法有些许中,比较简单但很慢的是用,适用于初学者,
Selenium + PhantomJs/chromedriver
就加上个
执行脚本,进度条拉到最底部
driver.execute_script(‘window.scrollTo(0,document.body.scrollHeight)’)

还有一种就是分析每次加载的变化是哪些
通过抓包或F12看network中的变化,在服务器发送过来的具体文件中找到我们需要的数据。一般是个较长的json文件,再从文件中分析每次加载变化的是哪些,哪些是需要的发送给服务器的数据,然后根据文件请求的方式(get/post),将确认好的数据按要求添加到发送的data中。

原生的多线程

在框架泛滥的年代写原生的已经很少了,也列举下吧。可用消息队列或者管道或者共享内存,
基本流程是:
1.将一堆要请求的url放到urls的消息队列中
2.将一堆通过请求获取到的带解析的html放到htmls的消息队列中
3.创建多个线程进行请求url 和解析html(需解决最后解析时阻塞问题,设置超时或者其他方法即可)
4.回收线程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值