单线程爬虫

2024-04-28 15:08
文章标签 爬虫 单线程

本文主要是介绍单线程爬虫,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Requests介绍与安装

1 Requests介绍:HTTP for humans

是Python的第三方HTTP库,可方便地实现Python的网络连接;

完美替代了Python的urllib2模块;

拥有更多自动化、更友好的用户体验、更完善的功能;


2 安装

在Windows下,执行pip install requests;

在Linux下,执行sudo pip install requests;


3 第三方库安装技巧

3.1 少使用easy_install,因为只能安装不能卸载;

3.2 多使用pip方式安装;

3.3 撞墙怎么办?请戳http://www.lfd.uci.edu/~gohlke/pyhtonlibs/


4 举例

教学视频是根据上述网站下载requests库,但现在没法打开,因此在搜索引擎上搜索查找到requests下载链接:https://pypi.python.org/pypi/requests/

选择“requests-2.10.0-py2.py3-none-any.whl (md5)”进行下载;

修改下载文件的拓展名为.zip,并复制requests文件夹到Python安装目录下的Lib文件夹下即完成安装;




二、第一个网页爬虫

使用requests获取网页源代码,再使用正则表达式匹配出感兴趣的内容,这是单线程简单爬虫的基本原理;

1 使用requests获取网页源代码

1.1 直接获取源代码

#-*-coding:utf8-*-
import requestshtml=requests.get('http://www.nowcoder.com/courses')print html.text

但有时通过上述Python程序是无法获取网页源代码,因为有的网页会有反爬虫机制;


1.2 修改HTTP头获取源代码;

import re
import requests# 相当于面具,让访问的网站误以为是浏览器再查看源代码
# 获取User-Agent内容:在该网页右击选择审核元素,切换到Network栏,刷新页面,随便点击一项,在Headers一栏最下方就有相关信息
# hea是字典,键是User-Agent,值就是后面一长串内容
hea={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36'}# 在此处调用hea
html=requests.get('http://jp.tingroom.com/yuedu/yd300p/',headers=hea)# 将编码转为utf-8,否则中文会显示乱码
html.encoding='utf-8'print html.text


2 requests配合正则表达式提取感兴趣的内容:打印该网页中的日文

先获取整个网页源代码;

再查看想要获取的内容的上下文有什么共同点,可以看到想要获取的内容都是以<span style="color:#666666;">开头,以</span></p></li>结尾,中间部分就是带获取内容(.*?);

import re
import requestshea={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36'}html=requests.get('http://jp.tingroom.com/yuedu/yd300p/',headers=hea)html.encoding='utf-8'# print html.textcourse=re.findall('<span style="color:#666666;">(.*?)</span></p></li>',html.text,re.S)for i in course:print i

执行结果:

第二章 昔々、といってもせいぜい二十年ぐらい前のことなのだ...
挪威的森林(中日对照) 内容简介: 汉堡机场一曲忧郁的《挪...
藤野先生名文选读中日文对照 東京も格別のことはなかつた。上...
夏目漱石 我是猫(中日对照) 吾輩は猫である 夏目漱石 一 吾輩...
それお皿の絵柄よ 足のケガで中クラスの総合病院に入院しまし...
あるけちん坊(ぼう)な男がおりました。 毎日毎日,ご飯どき...
あるところに,たいへんへそまがりな息子(むすこ)がおりま...
向こうから,お医者(いしゃ)がやってきました。そこへ店(...
お盆休み(ぼんやすみ)に帰ってきた者(もの)同士(どうし...
昔(むかし),三太(さんた)という,ばかな息子がおりまし...
ある日のこと。 そこつ者が,瀬戸物(せともの)屋(や)へ,...
植木(うえき)の大好きな旦那(だんな)がおりました。 ある...
息子が表(おもて)で,凧(たこ)を揚(あ)げておりました...
ある夜(や)のこと,お寺(てら)の庭(にわ)で,小僧(こ...
はくうんしゅうしょく 一匹のトンボが夏の終わりを告げるわけ...
先日、ある研修で聞いた言葉ですが、 「学習」の本質を端的に...
闇夜(やみよ)に,二人の若い男が,こそこそ話しております...
ある役人が誕生日のときに、下役たちは彼が鼠年だと聞き、お...
東京の郊外に住む木村さんは、お酒を飲んでの失敗の多い人で...
ある人が新調した絹の裾/裙(すそ、はかま)を着用して外出...




三、向网页提交数据

1 Get与Post介绍

Get从服务器上获取数据,通过构造url中的参数实现功能;

Post向服务器传送数据,将数据放在header提交数据;


2 分析目标网站

目标网站:https://www.crowdfunder.com/browse/deals

爬取内容:网页的所有公司名称

辅助工具:Chrome浏览器的审核元素中Network功能

核心方法:requests.post

核心步骤:构造表单 -> 提交表单 -> 获取返回信息


1‘ 打开网站,点击查看网页源代码,这是网页爬虫的必要习惯!

在源代码中,可先用公司名称搜索其在源代码中的位置,如公司名称MYFORCE在源代码位置如下:


公司名称可使用正则表达式"card-title">(.*?)</div>进行匹配,此时可匹配到19个公司名称;


2‘ 在网站正下方点击SHOW MORE按钮,出现更多公司信息(以追加形式);

值得注意的是,此时网站网址仍是https://www.crowdfunder.com/browse/deals,说明该网站使用异步加载技巧

异步加载,指先加载网页基本框架,对于剩下的信息,需要哪里就加载哪里,提高网页加载效率

重新打开网站源代码,搜索"card-title">,发现仍然是19,说明后面加载的公司信息在源代码中无法找到;


3使用Chrome的审核元素中Network功能,当前没有任何信息;点击SHOW MORE按钮,出现信息,点击第一条:

在General项,请求方法是Request Method: POST,说明使用POST向网页提交数据;

提交地址是https://www.crowdfunder.com/browse/deals&template=false


在Form Data项,页数是Page: 2,说明构造Form Data向网页进行提交,可以得到想要的信息;



4‘ 打开Pycharm,

#-*-coding:utf8-*-
import requests
import re
url='https://www.crowdfunder.com/browse/deals&template=false'
data={   # 字典,有2个元素,构造Form Data'entities_only':'true','page':'1'   # 可修改页数值
}
html_post=requests.post(url,data=data)
title=re.findall('"card-title">(.*?)</div>',html_post.text,re.S)
for each in title:print each

结果执行:

MYCROWD QA
DIGITZS
GOCOIN
SANTO DIABLO MEZCAL
RAGEON!
SELFIE WITH ME




四、实战——极客学院课程爬虫

1 目标网站

http://www.jikexueyuan.com/course/


2 目标内容

前20页的课程名称、课程介绍、课程时间、课程等级、学习人数


3 涉及知识

requests获取网页、re.sub换页、正则表达式匹配内容


4 抓取关键步骤

1’ 打开网站,首页网站为http://www.jikexueyuan.com/course/;点击下一页后,第2页网站为http://www.jikexueyuan.com/course/?pageNum=2;

则首页网站也可以是http://www.jikexueyuan.com/course/?pageNum=1;


2‘ 首先点击审核元素中放大镜图标,将鼠标箭头放在第一个课程的名称处,审核元素就会自动定位到当前源代码相应位置,在其附近也可找到课程介绍、时间、等级和学习人数对应的源代码位置;


3’ 采用先抓大后抓小的原则。对于先抓大,在审核元素中,每个课程信息都是在标签<li id="和标签</li>之间,可以使用re.findall()匹配出所有课程信息并保存在列表中;对于再抓小,对列表进行遍历,每个课程信息进行细划分,如下:

课程名称在标签class="lessonimg" title="和标签" alt=之间;

课程介绍在标签display: none;">和标签</p>之间;

课程时间在标签<em>和标签</em>之间;

课程等级在标签<em>和标签</em>之间;

学习人数在标签"learn-number">和标签</em>之间;

其中,对于相同的标签标识,可使用re.findall()匹配出2个符合要求的元素,课程时间在列表的第一个元素,课程等级在列表的第二个元素;


5 编写程序——从小到大功能实现

5.1 实现单页的课程信息爬取

#-*-coding:utf8-*-
import requests
import reimport sys
reload(sys)
sys.setdefaultencoding("utf-8")url='http://www.jikexueyuan.com/course/?pageNum=1'html=requests.get(url).text
course=re.findall('(<li id=".*?</li>)',html,re.S)
info={}for each in course:info['title']=re.search('class="lessonimg" title="(.*?)" alt=',each,re.S).group(1)info['detail'] = re.search('display: none;">(.*?)</p>', each, re.S).group(1)temp=re.findall('<em>(.*?)</em>',each,re.S)info['date']=temp[0]info['class']=temp[1]info['number']=re.search('"learn-number">(.*?)</em>',each,re.S).group(1)f = open('info.txt', 'a')f.writelines('title: '+info['title']+'\n')f.writelines('detail: ' + info['detail'] + '\n')f.writelines('date: ' + info['date'] + '\n')f.writelines('class: ' + info['class'] + '\n')f.writelines('number: ' + info['number'] + '\n\n')f.close()


5.2 实现20页的课程信息爬取

#-*-coding:utf8-*-
import requests
import reimport sys
reload(sys)
sys.setdefaultencoding("utf-8")url='http://www.jikexueyuan.com/course/?pageNum=1'cur_url=int(re.search('pageNum=(\d+)',url,re.S).group(1))
page_group=[]
for i in range(1,21):links=re.sub('pageNum=\d+','pageNum=%s'%i,url,re.S)page_group.append(links)for link in page_group:print u'正在处理页面:'+linkhtml=requests.get(link).textcourse=re.findall('(<li id=".*?</li>)',html,re.S)info={}for each in course:info['title']=re.search('class="lessonimg" title="(.*?) alt=',each,re.S).group(1)info['detail'] = re.search('display: none;">(.*?)</p>', each, re.S).group(1)temp=re.findall('<em>(.*?)</em>',each,re.S)info['date']=temp[0]info['class']=temp[1]info['number']=re.search('"learn-number">(.*?)</em>',each,re.S).group(1)f = open('info.txt', 'a')f.writelines('title: '+info['title']+'\n')f.writelines('detail: ' + info['detail'] + '\n')f.writelines('date: ' + info['date'] + '\n')f.writelines('class: ' + info['class'] + '\n')f.writelines('number: ' + info['number'] + '\n\n')f.close()


5.3 实现使用类的课程信息爬取

#-*_coding:utf8-*-
import requests
import re# Windows下默认编码是GBK,网页默认编码是utf-8,编码不匹配易导致爬取内容乱码
import sys
reload(sys)
sys.setdefaultencoding("utf-8")class spider(object):def __init__(self):print u'开始爬取内容。。。'#getsource用来获取网页源代码def getsource(self,url):html = requests.get(url)return html.text#changepage用来生产不同页数的链接def changepage(self,url,total_page):now_page = int(re.search('pageNum=(\d+)',url,re.S).group(1))page_group = []for i in range(now_page,total_page+1): # 左闭右开link = re.sub('pageNum=\d+','pageNum=%s'%i,url,re.S)page_group.append(link)return page_group#geteveryclass用来抓取每个课程块的信息def geteveryclass(self,source):everyclass = re.findall('(<li id=.*?</li>)',source,re.S)return everyclass#getinfo用来从每个课程块中提取出我们需要的信息def getinfo(self,eachclass):info = {} # 字典info['title'] = re.search('lessonimg" title="(.*?)" alt',eachclass,re.S).group(1)info['content'] = re.search('display: none;">(.*?)</p>',eachclass,re.S).group(1)timeandlevel = re.findall('<em>(.*?)</em>',eachclass,re.S)info['classtime'] = timeandlevel[0]info['classlevel'] = timeandlevel[1]info['learnnum'] = re.search('"learn-number">(.*?)</em>',eachclass,re.S).group(1)return info#saveinfo用来保存结果到info.txt文件中def saveinfo(self,classinfo):f = open('info.txt','a')#追加方式打开for each in classinfo:f.writelines('title:' + each['title'] + '\n')f.writelines('content:' + each['content'] + '\n')f.writelines('classtime:' + each['classtime'] + '\n')f.writelines('classlevel:' + each['classlevel'] + '\n')f.writelines('learnnum:' + each['learnnum'] +'\n\n')f.close()#####程序入口
#如果是程序自己使用jikexueyuan.py,则__name__的值是__main__
if __name__ == '__main__':classinfo = [] # 空列表,用以保存课程信息url = 'http://www.jikexueyuan.com/course/?pageNum=1'jikespider = spider()    # 实例化spider()类all_links = jikespider.changepage(url,20)for link in all_links:print u'正在处理页面:' + linkhtml = jikespider.getsource(link)everyclass = jikespider.geteveryclass(html)for each in everyclass:info = jikespider.getinfo(each)classinfo.append(info)jikespider.saveinfo(classinfo)


6 涉及知识点总结

6.1 修改默认编码

Windows默认编码是GBK,网页默认编码是UTF-8,需设置默认编码,否则易导致爬取内容乱码;

注意:在设置前必须对sys模块进行reload;

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

6.2 __name__内置属性

如果import一个模块,则模块的__name__的值为模块文件名,不带路径或文件扩展名;

如果直接执行当前文件,则__name__的值为__main__。

6.3 类的定义和实例化

6.4 re.search(pattern, string, flag)方法

pattern为匹配的正则表达式,string为要匹配的字符串,flag为标志位;

匹配整个字符,只提取第一个符合要求的内容,返回一个正则表达式对象;

使用匹配对象函数group(n)获取第n个匹配字符串,或group()获取整个字符串;

6.5 re.findall(pattern, string, flag)方法

匹配所有符合要求的内容,结果以列表形式返回;

可使用下标对列表元素进行访问;

6.6 re.sub(pattern, repl, string)方法

pattern为匹配的正则表达式,repl为替换的正则表达式,string为要匹配的字符串;

如re.sub('123(.*?)','123%d'%123,s)表示将123后面的字符串替换成123,这里的%d可以是任何一个字母;

6.7 正则表达式\d+

\d表示[0-9]

\l表示[a-z]

\u表示[A-Z]

\w表示[a-zA-Z0-9]

\s表示任意空白字符

上述大写形式表示其相反意义,如\D表示非数字字符

+表示有多个,如\d+表示至少有1个、最多不限制的数字串

^表示以其后紧跟的字符类型开头,如^[0-9]表示以数字字符为开头,注意:[^0-9]表示非数字字符

$表示以其前紧跟的字符类型结尾

6.8 文件I/O

用file对象实现文件操作;

a 打开:open()方法

file_object=open(file_name[, access_mode]);

file_name表示要访问的文件名的字符串值,access_mode表示打开文件模式:只读r、写入w、追加a等;

b 关闭:close()方法

刷新缓存区重任何还没写入的信息,并关闭该文件;

file_object.close();

c 写:

write()方法:

file_object.write(string);

将任何字符串写入一个打开的文件;

writelines()方法:

file_object.writelines(sequence);

将序列以迭代形式写入一个打开的文件;

d 读:

read()方法:

string=file_object.read([len]);

从打开的文件中读取一个字符串,默认读到文件末尾,否则读取前len个字符,以字符串形式返回;

readline()方法:

string=file_object.readline();

从打开的文件中读取整行,包括换行符,以字符串形式返回;

sequence=file_object.readlines();

从打开的文件中读取所有行,以列表形式返回;

---------------------------------------------------------------

课程总结:

1 requests获取网页源代码

2 修改http头绕过简单的反爬虫机制

3 向网页提交内容


这篇关于单线程爬虫的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/943562

相关文章

Python3 BeautifulSoup爬虫 POJ自动提交

POJ 提交代码采用Base64加密方式 import http.cookiejarimport loggingimport urllib.parseimport urllib.requestimport base64from bs4 import BeautifulSoupfrom submitcode import SubmitCodeclass SubmitPoj():de

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目

Golang 网络爬虫框架gocolly/colly(五)

gcocolly+goquery可以非常好地抓取HTML页面中的数据,但碰到页面是由Javascript动态生成时,用goquery就显得捉襟见肘了。解决方法有很多种: 一,最笨拙但有效的方法是字符串处理,go语言string底层对应字节数组,复制任何长度的字符串的开销都很低廉,搜索性能比较高; 二,利用正则表达式,要提取的数据往往有明显的特征,所以正则表达式写起来比较简单,不必非常严谨; 三,使

Golang网络爬虫框架gocolly/colly(四)

爬虫靠演技,表演得越像浏览器,抓取数据越容易,这是我多年爬虫经验的感悟。回顾下个人的爬虫经历,共分三个阶段:第一阶段,09年左右开始接触爬虫,那时由于项目需要,要访问各大国际社交网站,Facebook,myspace,filcker,youtube等等,国际上叫得上名字的社交网站都爬过,大部分网站提供restful api,有些功能没有api,就只能用http抓包工具分析协议,自己爬;国内的优酷、

Golang网络爬虫框架gocolly/colly(三)

熟悉了《Golang 网络爬虫框架gocolly/colly 一》和《Golang 网络爬虫框架gocolly/colly 二》之后就可以在网络上爬取大部分数据了。本文接下来将爬取中证指数有限公司提供的行业市盈率。(http://www.csindex.com.cn/zh-CN/downloads/industry-price-earnings-ratio) 定义数据结构体: type Zhj

014.Python爬虫系列_解析练习

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈 PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈 Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈 优

urllib与requests爬虫简介

urllib与requests爬虫简介 – 潘登同学的爬虫笔记 文章目录 urllib与requests爬虫简介 -- 潘登同学的爬虫笔记第一个爬虫程序 urllib的基本使用Request对象的使用urllib发送get请求实战-喜马拉雅网站 urllib发送post请求 动态页面获取数据请求 SSL证书验证伪装自己的爬虫-请求头 urllib的底层原理伪装自己的爬虫-设置代理爬虫coo

Python 爬虫入门 - 基础数据采集

Python网络爬虫是一种强大且灵活的工具,用于从互联网上自动化地获取和处理数据。无论你是数据科学家、市场分析师,还是一个想要深入了解互联网数据的开发者,掌握网络爬虫技术都将为你打开一扇通向丰富数据资源的大门。 在本教程中,我们将从基本概念入手,逐步深入了解如何构建和优化网络爬虫,涵盖从发送请求、解析网页结构到保存数据的全过程,并讨论如何应对常见的反爬虫机制。通过本教程,你将能够构建有效的网络爬

0基础学习爬虫系列:网页内容爬取

1.背景 今天我们来实现,监控网站最新数据爬虫。 在信息爆炸的年代,能够有一个爬虫帮你,将你感兴趣的最新消息推送给你,能够帮你节约非常多时间,同时确保不会miss重要信息。 爬虫应用场景: 应用场景主要功能数据来源示例使用目的搜索引擎优化 (SEO)分析关键词密度、外部链接质量等网站元数据、链接提升网站在搜索引擎中的排名市场研究收集竞品信息、价格比较电商网站、行业报告制定更有效的市场策略舆情

0基础学习爬虫系列:程序打包部署

1.目标 将已经写好的python代码,打包独立部署或运营。 2. 环境准备 1)通义千问 :https://tongyi.aliyun.com/qianwen 2)0基础学习爬虫系列–网页内容爬取:https://blog.csdn.net/qq_36918149/article/details/141998185?spm=1001.2014.3001.5502 3. 步骤 1)不知道