要求:爬取51job网页上岗位的相关信息以csv和mysql存储
job.py
class JobSpider(scrapy.Spider):
name = 'job'
allowed_domains = ['51job.com']
start_urls = ['https://search.51job.com/list/000000,000000,0000,00,9,99,%25E7%25AE%2597%25E6%25B3%2595%25E5%25B7%25A5%25E7%25A8%258B%25E5%25B8%2588,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=']
url="https://search.51job.com/list/000000,000000,0000,00,9,99,"+"算法工程师"+",2,%d.html?lang=c&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare="
page_num = 2 #设置初始页面为2
def parse(self, response):
item=JobproItem()
all_html = response.xpath("//script[@type='text/javascript']/text()")[0].extract() #提取script的数据
data = all_html.split("window.__SEARCH_RESULT__ = ")[1] #对字符串进行切片操作
dic = json.loads(data) #将JSON格式数据转换为字典形式
a = dic.values() #取字典中的值
shuju=[shuju for shuju in a if shuju != []][0] #将空列表去除
for i in shuju:
item['job_name'] = i['job_name'] #获得岗位名称
item['salary'] = i['providesalary_text'] #获得岗位薪资
item['place'] = i['workarea_text'] #获得工作位置
item['pub_time'] = i['updatedate'] #获得岗位信息发布时间
item['benifits'] = " ".join(i['jobwelf_list']) #获得岗位福利
item['info_url'] = i['job_href'] #获得岗位详细页的url
yield scrapy.Request(item['info_url'],meta={'item':copy.deepcopy(item)},callback=self.detail) # 调用detail函数来对详细页的数据进行解析
# break
if self.page_num <= 210:
self.page_num += 1 # 页面自增
print('爬第:%d 页' % self.page_num) #显示爬取的页数
new_url = self.url % self.page_num #将每次更新的url保存
# 手动请求发送:callback专门用作数据解析的方法,这里用的还是parse的解析方法
yield scrapy.Request(url=new_url, callback=self.parse)
# callback 回调函数,页面进行解析
def detail(self,response):
item = response.meta['item']
item['info']=' '.join(response.xpath("//div[contains(@class,'job_msg')]//p/text()").getall())
# item['contact']=response.xpath("div[@class='bmsg inbox']/p[@class='fp']/text()")
# item['contact']=" ".join(item['contact'])
yield item
yield scrapy.Request(item[‘info_url’],meta{‘item’:copy.deepcopy(item)},callback=self.detail)
此处的item:copy.deepcopy(item).可以解决爬取的第一列数据相同的情况。
我们寻常意义的复制就是深复制,即将被复制对象完全再复制一遍作为独立的新个体单独存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响。
—–而浅复制并不会产生一个独立的对象单独存在,他只是将原有的数据块打上一个新标签,所以当其中一个标签被改变的时候,数据块就会发生变化,另一个标签也会随之改变。这就和我们寻常意义上的复制有所不同了。
if self.page_num <= 210:
self.page_num += 1 # 页面自增
print('爬第:%d 页' % self.page_num) #显示爬取的页数
new_url = self.url % self.page_num #将每次更新的url保存
# 手动请求发送:callback专门用作数据解析的方法,这里用的还是parse的解析方法
yield scrapy.Request(url=new_url, callback=self.parse)
循环爬取每一页信息的代码。
也可以
url中需要找到改变页码的位置
item['info']=' '.join(response.xpath("//div[contains(@class,'job_msg')]//p/text()").getall())
使用contains来匹配class。
don’t_filter:
scrapy默认过滤掉重复的之前爬过的url,在request参数中添加dont_filter=True
设置不过滤url