Hello!您能点开我的博客,我感到很荣幸,希望能对您有帮助。我是第一次写,如有不足之处,还请前辈多多指教。
以下是我写的一个爬虫小项目,爬取了智联招聘的一个网页里对于找工作的亲们比较感兴趣的几条信息,并把信息整理到了sqlite数据库里,
- 创建一个爬虫文件,如zhilianspider.py
import scrapy
from CommmonSpider.items import CommmonSpiderItem
class ZhilianSpiderSpider(scrapy.Spider):
# 爬虫名称,唯一
name = 'zhilian_spider'
# 允许访问的域
allowed_domains = ['www.zhaopin.com']
# 起始网址
start_urls = ['https://jobs.zhaopin.com/447375014271949.htm']
# 爬虫入口
def parse(self, response):
# 保证爬虫框架能够运行起来
# print(response.text)
# 通过Xpath提取字段
# 提取响应路径为所有h1标签的文本内容(字符串形式)第一个
job_title = response.xpath('//h1/text()').extract_first()
# 提取响应路径为所有p标签的文本内容以字符串形式组成列表
job_descriptor=response.xpath("//p/text()").extract()
job_addr = response.xpath('//a[@href="http://www.zhaopin.com/lanzhou/"]/text()').extract_first()
job_salary = response.xpath('//strong/text()').extract()[3]
# 设置空字符串
job_result=""
# 遍历列表
for job_str in job_descriptor:
#拼接字符串
job_result+=job_str
# 解析工作详细信息页,将结果封装为指定的Item,
# 送到piplines进一步存入数据库
item=CommmonSpiderItem()
item["job_title"] = job_title
item["job_des"]=job_result
item["job_addr"] = job_addr
item["job_salary"] = job_salary
# 将爬取到的数据返回到pipelines.py,存储到数据库
yield item
- 打开items.py文件
import scrapy
class CommmonSpiderItem(scrapy.Item):
"""
定义数据模型类,需要打开settings中的ITEM_PIPELINES 才能生效
"""
# 定义Item,继承scrapy.Item类,
# 并将所有字段都定义为scrapy.Field类型
job_des=scrapy.Field()
job_title=scrapy.Field()
job_salary=scrapy.Field()
job_addr=scrapy.Field()
打开 settings.py,使ITEM_PIPELINES 生效
在settings.py中找到 ROBOTSTXT_OBEY ,将True改为 False。
- 打开pipelines.py文件
#导入SQLite驱动
import sqlite3
# 数据装数据库
class CommmonspiderPipeline(object):
"""
处理spider解析过的item结果,可以存入数据库或文件,需要打开
settings中的ITEM_PIPELINES 才能生效
"""
# 定义对象
def __init__(self):
# 连接到SQLite数据库,数据库文件是job.db
# 如果文件不存在,会自动在当前目录创建
self.conn=sqlite3.connect("job.db")
#创建一个Cursor随机数据源
self.cursor=self.conn.cursor()
# 执行一条SQL语句,创建jobs表
# self.cursor.execute("create table IF NOT EXISTS jobs(jobs text);")
self.cursor.execute("create table jobs( job_des text, job_title text,job_salary text,job_addr text) ")
# 提交数据
self.conn.commit()
def process_item(self, item, spider):
# 给jobs表添加字段(表格第一行的如工作、详情描述、地点、薪资等)
jobs_insert = 'insert into jobs(job_des,job_title,job_salary,job_addr) values(?,?,?,?)'
# 把item[]的值分别添加到对应的字段下边
jobs_data = (item["job_des"], item["job_title"],item["job_salary"],item["job_addr"])
# 执行上面两句命令
self.cursor.execute(jobs_insert, jobs_data)
# 提交数据
self.conn.commit()
- 打开middlewares.py文件,拉到最后
- 注意:代码完成后打开 settings.py,使DOWNLOADER_MIDDLEWARES 生效
from selenium import webdriver
from selenium.webdriver.firefox.options import Options as FOptions
from selenium.common.exceptions import TimeoutException
import time
from scrapy.http import HtmlResponse
# 代理服务器
# 当引擎从调度器中取出request进行请求 发送给下载器之前
# 会先执行当前爬虫的中间件,在中间件中使用selenium
# 请求这个request,拿到动态网站的数据
# 然后将请求返回给spider爬虫对象
class SeleniumMiddleware(object):
"""
Selenium中间件,用来使用浏览器模拟下载请求
,注意打开settings中的DOWNLOADER_MIDDLEWARES才能生效
"""
def __init__(self):
# 初始化一个Firefox实例
self.options=FOptions()
# 设置无界面
self.options.add_argument('-headless')
self.browser=webdriver.Firefox(executable_path="D:/ruanjian\geckodriver\geckodriver",
firefox_options=self.options)
def process_request(self,request,spider):
"""
该方法在中间件被激活的时候系统自动调用,处理requset请求
spider.name可以区分不同的爬虫
:param request:
:param spider:
:return:
"""
try:
# 获取请求的url网页链接内容
self.browser.get(request.url)
except TimeoutException as e:
print('超时')
# 休眠2秒
time.sleep(2)
# 请求的信息为获取的请求信息
# 生成HtmlResponse,将浏览器模拟的下载结果返回给我们的spider,
# 结果存在self.browser.page_source(原码)
# 结果是整个页面的html代码
return HtmlResponse(url=self.browser.current_url,
body=self.browser.page_source,
encoding="utf-8",request=request)
- 如果想要随机更换User-Agent,打开middlewares.py文件,拉到最后
- 注意:要去settings.py里使USER_AGENT失效,
并在DOWNLOADER_MIDDLEWARES里面添加’CommmonSpider.middlewares.RandomUserAgentMiddleware’: 543,(数字可以更改)
#导入浏览器用户代理模块
from fake_useragent import UserAgent
# 随机更换User-Agent
class RandomUserAgentMiddleware(object):
def __init__(self,crawler):
# 子类RandomUserAgentMiddleware调用父类object的__init__()方法
# 即用父类的初始化方法来初始化继承的属性
super(RandomUserAgentMiddleware, self).__init__()
#实例化浏览器用户代理模块类
self.ua=UserAgent()
# 随机获取浏览器类型
self.random_ua=self.ua.random
# 函数上面用上装饰符@classmethod,
# 函数里有一个必写形式参数cls用来接收当前类名称
# 定义这个方法,Scrapy会把当前的爬虫传递到方法里来
@classmethod
# 重载from_crawler方法
def from_crawler(cls,crawler):
# 将crawler返回给类
return cls(crawler)
# 重载process_request方法
def process_resquest(self,request,spider):
# 将浏览器代理信息添加到Requests请求
request.headers.setdefault('User-Agent',self.ua.random)
- 最后打开Terminal 进入爬虫项目,运行命令行scrapy crawl zhilian_spider,得到下面数据库表