python爬虫
2021-05-17 14:13:14 20 举报
AI智能生成
爬虫思维导图,不定时更新项目文件
作者其他创作
大纲/内容
python爬虫
import requests # 网页下载工具from bs4 import BeautifulSoup # 分析网页数据的工具from scrapy.cmdline import excute #调用后可执行scrapy脚本 excute([\"scrapy\
python模块
写入json文件的逻辑
生成md_5值
设置文件路径
添加当前文件的上上个目录的目录名的路径
添加当前文件的目录路径(当时用非绝对路径时)
path1 = os.path.abspath(os.path.dirname(__file__))
添加当前文件的绝对路径
list使用filter函数过滤
page_urls = filter(lambda x:True if x.startswith(\"https\
将list中的元素修改成“,”隔开的字符串
raink_item = \
date与时间、时间戳的转换
时间戳转换成date
datetime.datetime.fromtimestamp(self[\"ans_create_time\"]).strftime(\"%Y/%m/%d %H:%M:%S\")
str类型时间转换成datetime
年月日转换成datetime类型
数据类型转换
str转换成int(带千位分隔符,使用replace替换)
int(get_number(\"\".join(self[\"comment_num\"])).replace(\
tuple类型和list类型转换成·str类型
\"\".join(list(x))
两个list组成一个字典dict
生成随机数字
爬虫爬取机制结构
url管理器
防止重复抓取(最小功能范围)1.添加新的url到待爬去集合中 3.获取待爬取url2.同时判断待添加的url是否在容器中 4.同时判断是否还有待爬取的url 5.将url从待爬取移动到已爬取
实现方式1.内存: 将待爬取url和已爬取url存放到url集合set()中2.关系型数据库:mysql:urls(url.is_crawled)is_crawled标志url是否被爬取3.缓存数据库: redis:将爬取url和已爬取url存放到set中
url下载器
import urllib2url = \"http://www.baidu.com\"第一种方法response = urllib2.urlopen(url)print response.gedcode() 访问url后的获取码print response.read() 访问url的内容第二种方法(增加url头文件)request = urllib2.Request(url)request.add_header(\"user-agent\
url网页解析器
Beautiful Soup
beautlful soup --- python第三方库,用于html或xml中提取数据pip install beautifulsoup4from bs4 import BeautifulSoup
访问节点信息node.name 获取查找到的该节点的名字node['href'] 获取查找到的a节点的href属性node.get_text() 获取a节点下的文字
给定一个html_doc文件,获取所有链接信息html_doc= \" \
session、cookie的区别
cookie
浏览器的本地存储方式,是以dict的形式存储{\"sessionkey\":\"value\"}value在浏览器中为一段文本,浏览器会自动对其解析
浏览器向服务器发起无状态请求,服务器返回请求数据并返回一个标志id,浏览器将id存储到本地cookie上,当下次浏览器带着有请求id的报文到服务器上时,服务器就能判断出该浏览器上次请求的内容
session
由于cookie不安全性考虑:本地cook不能保存用户名和密码,服务器在返回请求数据和标志id时,将登录信息保存服务器本地,并把登陆信息形成session_id返回给浏览器,当下次浏览器进行登录时,将本地的session_id发送给服务器时,服务器通过session_id查找浏览器的登录信息进行匹配登陆
http常见状态码
200 :请求被处理成功301/302:永久性重定向/临时重定向403 :没有权限访问404 :表示没有对应的数据500 :服务器错误503 :服务器停机或正在服务
分支主题
scrapy框架
scrapy框架图
1.spider通过yield Request发出一个request请求,通过engine将request发送给scheduler2.scheduler收到request,通过engine将request通过downloader middleware层层过滤后发送给downloader3.downloader通过downloader middleware过滤返回一个response,通过spider middleware过滤后engine转发给spiders4.spiders通过spider middleware过滤后返回items和requests,engine收到后,判断items发给item pipelines进行下载,requests发送给scheduler重新进入循环步骤2
源码在site-page/tscrapy/core中
request和response的参数
request
url:url回调函数:callback=Nonemethod='GET'/'POST'头部信息:headers=Nonebody=Nonecook信息:cookies=None(可以是或list一个dict)传入下一个函数的参数:meta=None设置编码:sencoding='utf-8'影响scheduler的调度优先级:priority=0判断多个request是否被过滤:dont_filter=False(不被过滤)错误回调函数:errback=None
方法:copy()、replace()查看scrapy.org官方文档
response
url:url状态码:status = 200头部信息:headers=None页面信息:body=b' 'flags=Nonerequest=None
方法:copy()urljoin()replase()
子类:TextResponseHtmlResponseXmlResponse
HtmlResponse:HtmlResponse继承了TextRensponseTextRensponse有两个方法xpath,css
做云图
创建并建立用户mkdir demo ; cd demo安装wheel库pip install wheel下载并安装词云模块http://www.lfd.uci.edu/~gohlke/pythonlibs/pip install wordcloud-1.3.2-cp36-cp36m-win32.whl安装notebookpip install jupyterjupyter notebook
网上爬取的数据生成jay.txt文本
filename = \"jay.txt\"with open(filename) as f: mytext = f.read()
mytext
from wordcloud import WordCloudwordcloud = WordCloud().generate(mytext)
中文引入分词工具,及中文字体下载到demo目录中文字体:https://s3-us-west-2.amazonaws.com/notion-static/b869cb0c7f4e4c909a069eaebbd2b7ad/simsun.ttf安装结巴:pip install jiebaimport jiebamytext = \" \".join(jieba.cut(mytext))修改:wordcloud = WordCloud(font_path = \"simsun.ttf\").generate(mytext)
1.python使用beautlfulsoup爬取百度百科网页
spider_main(爬虫主函数)
url_manager(url管理器)
url_downloader(url下载器)
url_parser(url分析器)
spider_output(内容输出器)
vir虚拟环境及scrapy的安装
windows(wrapper)
windows
安装虚拟环境windows:(需要pip和python环境,pip下载解压后再cmd中运行python setup.py install,并把python\\Scripts路径加到path中)安装虚拟环境:pip install virtualenv新建虚拟环境:virtualenv --python /usr/bin/python3 scrapy_test(使用python的真实路径)进入环境运行环境:cd scrapy_test\\ activate.bat deactivate.bat在虚拟环境中安装scrapy:pip install -i https://pypi.douban.com/simple scrapy在虚拟环境中你所需要的目录下安装project目录:scrapy startproject scrapy_bolezaixian在虚拟环境中的project目录下安装pypiwin32 :pip install pypiwin32
linux
linux:安装虚拟环境:yum -y install python-virtualenv新建虚拟环境:virtualenv -p /usr/bin/python3 scrapy_test(virtualenv scrapy_test)进入环境运行环境:cd scrapy_test/bin source activate source deactivatelinux(wrapper版scrapy)安装依赖包yum install libxslt-devel libffi libffi-devel python-devel gcc openssl openssl-devel tar xf pyOpenSSL-0.11.tar.gz -C /usr/local/src/python setup.py install安装scrapyeasy_install -U Scrapy**************************************************************************安装Twistedwget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz -P /opt/tar zxvf setuptools-0.6c11.tar.gz -C /usr/local/src/python setup.py install安装lxmleasy_install Twistedeasy_install -U w3libeasy_install lxml安装pyOpenSSLwget http://launchpadlibrarian.net/58498441/pyOpenSSL-0.11.tar.gz -P /opt/
字段分析语法
xpath语法
xpath语法text() :以文本格式输出data数据值selector方法extract() :只输出data值strip() :除去换行,回车,空格等标识符输出list值replace(“。”,“”) :替换 把。换成空格contains() :包含()内函数就匹配成功@href :等同于::attr()title = response.xpath('//*[@id=\"post-111585\"]/div[1]/h1/text()').extract()[0]creat_date = response.xpath('//*[@id=\"post-111585\"]/div[2]/p/text()').extract()[0].replace(\"·\
css语法
css语法::text :等同于xpath中的text()::attr(href) :获取href=“”的数据extract()[0] extract_first(\"\") :当数组为空时会报错,最好用后者代替yield :讲给scrapy下载Request(url=\"\
2.使用scrapy爬取伯乐在线网页
scrapy爬取伯乐在线网页
main函数(在scrapy_spide总目录下)
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2017/9/3 14:21# @Author: jecht# @File : main.pyimport sysimport osfrom scrapy.cmdline import executesys.path.append(os.path.dirname(os.path.abspath(__file__)))execute([\"scrapy\
from scrapy.cmdline import excute #调用后可执行scrapy脚本 excute([\"scrapy\
spiders(所有spider的总目录)
jobbole.py(通过模板scrapy genspider jobbole blog.jobbole.com创建)
文章的列表页爬取,并把每篇文章的url和下一页的url交给scrapy下载
.extract()[0] #选取有效字段第一个[1]表示第二个可以换成extract_first(\"\
每个页面的item的爬取
通过分别定义每个item的内容进行加载
通过itemloader加载item
# 通过itemloader加载itemfront_image_url = response.meta.get(\"front_image_urls\
实例化item模板,并将填充后yield的数据交给pipeline下载
1.在item下编写jobbole的实例化项目
通过自定义item进行item Filed
class JobboleScrapyItem(scrapy.Item): front_imagr_url = scrapy.Field() title = scrapy.Field() datetime = scrapy.Field() prase_number = scrapy.Field() collections_number = scrapy.Field() comments_number = scrapy.Field() targe_list = scrapy.Field() content = scrapy.Field() front_image_path = scrapy.Field() url = scrapy.Field() url_object_id = scrapy.Field()
将所有需要填充的数据加入item中,并规范数据类类型为filedscrapy的数据类型只有filed
1.在setting中设置你的pipeline的优先使用权2.使用指定os.path功能指定image的路径3.'scrapy.pipelines.images.ImagesPipeline'定制化你的图片,可以在pipeline中重新定义一个class,在class中引用images包中的ImagePipeline,使用该class的函数功能,实现控制图片文件的格式,和过滤非重要的图片4.IMAGE_URLS_FIELD,IMG_STORE
交给pipelines爬取数据并下载到相应文件或数据库
设置settings开启执行pipeline的顺序
将图片保存到本地文件夹
将文件下载到本地生成json文件
自定义下载到本地json文件
利用scrapy下载到本地json文件
from scrapy.exporters import JsonItemExporterclass ScrapyItemExportersPipeline(object): def __init__(self): self.file = open(\"scrapy_exporter.json\
数据下载到mysql数据库中
通过同步操作将数据库同步到mysql
import MySQLdbclass ScrapyMysqlExporterPipline(object): def __init__(self): self.conn = MySQLdb.connect(\"127.0.0.1\
通过异步操作将数据同步到mysql
3.使用scrapy登陆知乎爬取知乎网站
知乎登录
使用request库登录知乎
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2017/9/20 9:59# @Author: jecht# @File : zhihu_login_request.pyimport timeimport cookiejarimport requestsfrom PIL import Imageimport retry: import cookielibexcept: import http.cookiejar as cookielibsession = requests.session()session.cookies = cookielib.LWPCookieJar(filename=\"cookies.txt\")try: session.cookies.load(ignore_discard=True)except: print(\"cookie未能加载\")url = \"https://www.zhihu.com\"#agent = \
获取xsrf
获取captcha验证码
def get_captcha(): t = str(int(time.time()*1000)) captcha_url = 'https://www.zhihu.com/captcha.gif?r=' + t + \"&type=login&lang=cn\
表单登陆
加载cookie
判断是否登录?
def get_ingore(): ignore_url = \"https://www.zhihu.com/inbox\
使用scrapy的request登陆知乎
# -*- coding: utf-8 -*-import jsonimport reimport scrapyimport timefrom PIL import Imageimport scrapy_projectimport requestsclass ZhihuSpider(scrapy.Spider): name = 'zhihu' allowed_domains = ['www.zhihu.com'] start_urls = ['http://www.zhihu.com/'] header = { \"Host\": \"www.zhihu.com\
编写登陆函数,函数中获取登入所需的xsrf,以及空白的captcha字段通过scrapy.Request()函数,回调给下一个login_after函数,并通过meta传入post_data数据
通过引入Image函数,实现验证码图片的查看功能通过抓包,查看到
爬取知乎数据
1.爬取总览页
1.headers可以通过setting中定义默认的,否则每次request时都需要定义headers2.通过parser函数,爬取总览页,并爬取每一个详情页的url进行yield给详情页分析函数3.并通过next_url进行循环给自身,一直爬取,直到爬取到最后一页
2.爬取详情页
3.编写item
子主题
4.编写pipeline
4.使用scrapy的crawlspider爬取拉钩网
使用crawl模板,不是用默认的basic模板
1.进入项目所在文件夹cd d:\\python_project\\scrapy_project\\scrapy_project2.进入虚拟环境workon scrapy_virtualenv2.查看spider模板列表scprapy genspider --list3.使用crawl模板scrapy genspider -t crawl lagou www.lagou.com
CrawlSpider源码分析
1.CrawlSpider类继承了__init__中的Spider类,Spider类的入口函数为start_requests()
2.start_requests函数默认的返回函数为parse函数,parse函数调用了_parse_response函数
if callback为if parse_start_url函数存在,则将cb_kwargs参数传入callback函数中得到一个数组数组又传入process_result函数中,由于初定义的两个函数为空,cb_res为空数组,后面可以自定义for循环将判断过可迭代的参数cb_res进行迭代,然后进行yield下载,如果两个自定义的函数没重写,则_parse_response基本属于没有调用
if _parse_reponse中默认的follw=True和settings设置中('CRAWLSPIDER_FLLOW_LINKS'=True)没有修改,则执行下面的for循环,通过linkextractor的函数遍历links,否则无法调用rule规则
3._parse_response函数允许scrapy中自定义调用parse_start_url和process_results对response进行处理4. 并通过_requests_to_follow调用scrapy中的rule,将response结果交给了rule中的LinkExtractor的extract_links方法用于将link全部抽取出来,并对每一个link进行一次类似yield scrapy.request(r)的功能5.在yield之前在r内通过_build_request再到_response_downloaded加入了处理
1.首先判断response是否是一个response对象2.seen是一个set(),后面通过for循环将response中的url提取并去重3._rules通过_compile_rules函数将每条rule进行添加callback和一些预处理方法4.将rules通过enumerate函数变成一个可迭代的rules,得到一个n或者rule5.links是等于拿着link_extractor在response中使用extracr_links方法进行抽取link(或者说url),并确定link不在seen中6.如果对使用extract_links方法匹配link_extractor的结果link不满意的话,可以再使用process_links函数再进行过滤一遍7.将最终确定数据全部加入到seen中8.通过process_request和build_requestdownload下来
6.LinkExtractor根据传进来的参数,例如(allow=r'Item/')或deny、allow_domains等其他参数7._build_request到_response_downloaded的处理是将response中的rule提取出来
最后又返回给_pare_response函数了
Rule和LinkExtractor的参数用法
Rule的参数
1.link_extractor:基本交给extract_link使用2.callback:回调函数,在logo.py中定义的3.cb_kwargs:传递给link_extractor的参数4.follow:判断是否跟踪满足本条rule的url5.process_links:对links传入预处理函数6.process_request=identity:identity是一个可以自定义的空函数,类似于process_links
LinkExtractor
LinkExtractor的参数
xpath处理xml,css处理html,当使用css时,会从继承的FilteringExtractor类中条用HTMLTranslator()去将css转化成xpath
LinkExtractor的extract_links函数
1.根据response的url调用get_base_url函数去获取url2.如果有设置restrict_xpath,则进行遍历路径进行xpath处理3.得到的符合路径的字段形成list4.将list进行遍历,分别执行_extract_links()匹配之前link_extractor的字段,形成一个links
编写rule和linkextractor进行爬取拉钩全站
编写items
class LagouItemLoader(ItemLoader): default_output_processor = TakeFirst()class LagouItem(scrapy.Item): title = scrapy.Field() url = scrapy.Field() url_object = scrapy.Field() degree_need = scrapy.Field() crawl_time = scrapy.Field() publish_time = scrapy.Field() targs = scrapy.Field() company_name = scrapy.Field() company_url = scrapy.Field() job_city = scrapy.Field() job_type = scrapy.Field() job_advantage = scrapy.Field() job_desc = scrapy.Field() job_addr = scrapy.Field() salsry_max = scrapy.Field() salsry_min = scrapy.Field() work_years_max = scrapy.Field() work_years_min = scrapy.Field()
在lagou.py中解析字段
5.爬虫与反爬虫策略
1.随机更换User-Agent
1.通过自建user_agent_list,使用random.randint获取随机UserAgent
(推荐!)1.通过github上的fake-useragent进行随机获取useragent
1.super(,self).__init__():使子类调用父类的属性并进行初始化函数
2.使用代理ip
使用ip代理
使用西刺免费的高匿ip代理将主机ip隐藏填入代理ip与端口request.meta[\"proxy\"] = \"https://183.71.136.98:8118\"
使用ip代理池
自己写一个爬虫,爬取西刺代理网站的高匿免费ip代理crawl_xici_ip.py
import datetimeimport requestsfrom scrapy.selector import Selectorimport MySQLdbconn = MySQLdb.connect(host=\"127.0.0.1\
在settings和middleware中,调用西刺代理ip
使用github上的开源库scrapy-proxies
功能比自己的写的更强大更齐全
使用github上官方收费的开源库scrapy-crawlera
使用洋葱网络
将ip经过多次的转发后达到隐藏ip的功能(但是需要用到vpn)
3.验证码识别
1.google开源工具tesseract-ocr
缺点:干扰比较大
2.在线打码
云打码
3.人工打码
超速打码
4.限速
http://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/autothrottle.html
1.在settings中设置最低的下载延迟:
DOWNLOAD_DELAY
2.在settings中设置更高的并发数:
CONCURRENT_REQUESTS_PER_DOMAIN 或( CONCURRENT_REQUESTS_PER_IP )
3.在settings中设置自动限速
AUTOTHROTTLE_ENABLED 启用autothrottle模式AUTOTHROTTLE_START_DELAY 设置自动限速的初始延迟(单位:秒)AUTOTHROTTLE_MAX_DELAY 设置自动限速的最大延迟(单位:秒)AUTOTHROTTLE_DEBUG 启用自动限速的调试模式
5.在不同情况下设置不同的settings
1.默认情况下不需要登陆状态,是不需要开启cookie值的,所以需要在settings中设置COOKIES_ENABLED = False
2.如知乎,需要的另外开启cookie状态的,则只需要在spider中的zhihu.py直接设置custom_settings={ COOKIES_ENABLED = True }
6.selenium动态网问网站
1.了解selinium
1.安装selenium
在虚拟环境下pip install selenium
百度selenium python api,找到官方文档,查找不同浏览器的drivers(firefox的试了很多次,需要对应版本都没成功)(使用了google的driver,地址:http://npm.taobao.org/mirrors/chromedriver/)(环境:python3.6.1,selinum 3.11,google浏览器65.0,chromedriver_win32.zip:2.37)
2.使用selinum的webdriver模块,自动加载网页
from selenium import webdriverbrowser = webdriver.Chrome(executable_path=\"D:\\python_project\\selenium_drviers\\chromedriver.exe\")browser.get(\"https://item.taobao.com/item.htm?spm=a230r.1.14.71.31207d9buGsqEv&id=561063544221&ns=1&abbucket=8#detail\")print(browser.page_source)
3.selenium的字段分析
1.使用scrapy自带的xml的字段分析
from scrapy.selector import Selectort_selector = Selector(text=bowser.page_source)t_selector.xpath( )t_selector.css( )
2.使用selinum的字段分析
browser.find_ele
2.使用selinum的webdriver.chrom()加载页面
1.用selnium模拟登陆知乎
from selenium import webdriverfrom scrapy.selector import Selectorbrowser = webdriver.Chrome(executable_path=\"D:\\python_project\\selenium_drviers\\chromedriver.exe\")browser.get(\"https://www.zhihu.com/signin\")browser.find_element_by_css_selector(\".Login-content input[name = 'username']\").send_keys(\"17512009387\")browser.find_element_by_css_selector(\".Login-content input[name = 'password']\").send_keys(\"wuting123\")browser.find_element_by_css_selector(\"button.SignFlow-submitButton\").click()
2.使用selinium爬取微博
1.使用微博开放平台:http://open.weibo.com/wiki/%E9%A6%96%E9%A1%B5
2.遇到的问题:无法定位元素
3.登陆微博(碰到验证码可以手动输入)
def weibo(): url = \"https://weibo.com/\" browser.get(\"https://weibo.com/\") time.sleep(5) browser.find_element_by_css_selector(\"div.WB_miniblog div[node-type='username_box'] input[name = 'username']\").send_keys(\"15870635250\") browser.find_element_by_css_selector(\"div.WB_miniblog div[node-type='password_box'] input[name = 'password']\").send_keys(\"tumeihong\") browser.find_element_by_css_selector(\"div.WB_miniblog div[node-type='normal_form'] div.info_list.login_btn a[node-type = 'submitBtn']\").click()
4.模拟下拉刷新(适用于javascript)使用javascripts代码
for i in range(3): browser.execute_script(\
window.scrollTo():把窗口调整到某个位置
document.body.scrollHeight:表示body标签最大可以滚动到的坐标
3.使用selinum设置chromdriver不加载图片
#不加载图片 chrom_opt = webdriver.ChromeOptions() prefs = {\"profile.managed_default_content_settings.images\":2} chrom_opt.add_experimental_option(\"prefs\
chrom_opt:调用chromOptions的方法prefs: 修改chromdriver的图片设置为2,表示不显示图片 导入外置的设置到chromOptions类中:chrom_opt.add_experimental_option() 把chrom_options=设置导入browser实例里
注意:webdriver.chrom()不能放在函数内,会闪退。可通过try......exception设置多个browser
3.使用无界面浏览器:phantomjs(多进程情况下phantomjs性能会下降很严重)
1.安装phantomjs
2.配置phantomjs
browser = webdriver.PhantomJS(executable_path = \"D:\\python_project\\selenium_drviers\\chromedriver.exe\")browser.get(\"http://www.baidu.com\")print (browser.page_sourse)browser.quit()
不显示图面,自动化运行
4.将selinum集成到scrapy中
通过建立middleware中间件
0 条评论
回复 删除
下一页